【洛谷】CYJian的水题大赛 解题报告
\(T1\):八百标兵奔北坡
这应该是一道较水的送分题吧。
理论上来说,正解应该是DP。但是,.前缀和优化暴力就能过。
放上我比赛时打的暴力代码吧(\(hl666\)大佬说这种做法的均摊复杂度为\(O(logn)\),总复杂度应为\(O(nlogn)\),可以接受):
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define N 1000
#define M 1000
using namespace std;
int n,m,Q,sum[N+5][M+5],a[N+5][M+5];
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0;int f=1;char ch;
while(!isdigit(ch=tc())) if(ch=='-') f=-1;
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
x*=f;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline bool check(int x,int y1,int y2)//利用前缀和,判断出第x行y1~y2范围内是否有山
{
return sum[x][min(y2,m)]-sum[x][max(y1-1,0)];
}
int main()
{
register int i,j;
for(read(n),read(m),read(Q),i=1;i<=n;++i)
for(j=1;j<=m;++j)
read(a[i][j]);
for(i=1;i<=n;++i)
for(j=1;j<=m;sum[i][j]+=sum[i][j-1],++j)//统计每一行的前缀和
if(a[i][j]>=max(max(a[i-1][j],a[i+1][j]),max(a[i][j-1],a[i][j+1]))),sum[i][j]=1;//若当前坐标有一坐山,则令sum[i][j]为1
while(Q--)
{
int x,y;bool could=false;read(x),read(y);
for(i=x;i;--i)
if(check(i,y-x+i,y+x-i))//判断是否可行
{
write(x-i),putchar('\n'),could=true;//可以就输出答案,并标记有答案
break;
}
if(!could) puts("Pool Babingbaboom!");//若标记无答案,则输出"Pool Babingbaboom!"
}
return 0;
}
\(T2\):灰化肥,会挥发
这道题一看到数据范围就会想到状压\(DP\)吧!(当然,也不乏有某些大佬会想到用模拟退火来做)
设用\(f[i][j]\)来表示在第\(i\)个谷仓,经过的谷仓集合为\(j\)时走过的最短路径,则$$f[i][j]=max(f[i][j],f[k][(j)xor (1<<(i-1))]+w[k][i])$$其中\(w[k][i]\)表示\(k\)与\(i\)的距离。
我们可以BFS预处理出两两仓库间的距离,然后\(DP\)即可
注:只可惜,我在比赛过程中不停爆0,比赛结束之后,请教\(hl666\)大佬才知道洛谷数据有\(BUG\),有字符串的题目不能打读优,结果白白爆\(0\),也算是一个教训吧!可怜我打了两个多小时的代码
代码如下:
#include<bits/stdc++.h>
#define R 500
#define C 500
#define N 16
using namespace std;
int n,r,c,cnt=0,H,T,x[R*C+5],y[R*C+5],Step[R*C+5],To[30],w[N+5][N+5],vis[R+5][C+5]={0},f[N+5][(1<<N)+5];
char ch[R+5][C+5];
struct Warehouse//存储每个谷仓的信息
{
char Name;
int x,y;
}s[N+5];
string S[N+5][(1<<N)+5];
//不能打读优QwQ
/*inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0;int f=1;char ch;
while(!isdigit(ch=tc())) if(ch=='-') f=-1;
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
x*=f;
}*/
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void BFS(int Now)//BFS预处理
{
while(H<=T)
{
if(ch[x[H]][y[H]]>='A'&&ch[x[H]][y[H]]<='Z') w[Now][To[ch[x[H]][y[H]]-'A']]=Step[H];
if(x[H]>1&&!vis[x[H]-1][y[H]]&&ch[x[H]-1][y[H]]!='*') vis[x[H]-1][y[H]]=1,x[++T]=x[H]-1,y[T]=y[H],Step[T]=Step[H]+1;//向上走
if(x[H]<r&&!vis[x[H]+1][y[H]]&&ch[x[H]+1][y[H]]!='*') vis[x[H]+1][y[H]]=1,x[++T]=x[H]+1,y[T]=y[H],Step[T]=Step[H]+1;//向下走
if(y[H]>1&&!vis[x[H]][y[H]-1]&&ch[x[H]][y[H]-1]!='*') vis[x[H]][y[H]-1]=1,x[++T]=x[H],y[T]=y[H]-1,Step[T]=Step[H]+1;//向左走
if(y[H]<c&&!vis[x[H]][y[H]+1]&&ch[x[H]][y[H]+1]!='*') vis[x[H]][y[H]+1]=1,x[++T]=x[H],y[T]=y[H]+1,Step[T]=Step[H]+1;//向右走
++H;
}
}
int main()
{
register int i,j,k;
for(cin>>r>>c>>n,i=1;i<=r;++i)
for(j=1;j<=c;++j)
{
cin>>ch[i][j];
if(ch[i][j]>='A'&&ch[i][j]<='Z') s[To[ch[i][j]-'A']=++cnt]=(Warehouse){ch[i][j],i,j};//将每一个谷仓的位置与名称存储下来
}
for(i=1;i<=n;++i)//对每个谷仓进行预处理
{
memset(vis,0,sizeof(vis));
vis[x[H=T=0]=s[i].x][y[0]=s[i].y]=1,Step[0]=0;
BFS(i);
}
for(i=1;i<=n;++i) for(j=1;j<=(1<<n)-1;++j) f[i][j]=1e9;//DP预处理
f[To[0]][1<<(To[0]-1)]=0,S[To[0]][1<<(To[0]-1)]="A";
for(j=1;j<=(1<<n)-1;++j)
for(i=1;i<=n;++i)
{
if(!(j&(1<<(i-1)))||!(j^(1<<(i-1)))) continue;
for(k=1;k<=n;++k)
if((i^k)&&(j&(1<<(k-1)))&&((f[k][j^(1<<(i-1))]+w[k][i]<f[i][j])||(f[k][j^(1<<(i-1))]+w[k][i]==f[i][j]&&S[k][j^(1<<(i-1))]+(s[i].Name)<S[i][j]))) f[i][j]=f[k][j^(1<<(i-1))]+w[k][i],S[i][j]=S[k][j^(1<<(i-1))]+(s[i].Name);
}
int Min=1e9;string ans;
for(i=1;i<=n;++i)
if(f[i][(1<<n)-1]<Min||(f[i][(1<<n)-1]==Min&&S[i][(1<<n)-1]<ans)) Min=f[i][(1<<n)-1],ans=S[i][(1<<n)-1];//统计答案
return write(Min),putchar('\n'),cout<<ans,0;
}
\(T3\):红鲤鱼与绿鲤鱼
很明显,这是一道简(fan)单(ren)的数学题。(\(ykh\)大佬\(3min\)切了此题)。
读题,我们可以发现,无论红鲤鱼的出现时间如何变化,罚时始终是一样的。所以,我们只需要管绿鲤鱼出现的时间,因为只有这个才会影响答案。
仔细考虑一下,我们可以推出下面这个式子:$$\frac{5(2A+B+1)+5C_{B+A-1}^{B-1}(A+B+1)\frac{A+B}{2}}{2}$$
然后,即可暴力去求答案。代码如下:
#include<bits/stdc++.h>
#define ULL unsigned long long
#define YKH 998244853
using namespace std;
ULL n,m;
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(ULL &x)
{
x=0;ULL f=1;char ch;
while(!isdigit(ch=tc())) if(ch=='-') f=-1;
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
x*=f;
}
inline void write(ULL x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline ULL Inv(ULL x,ULL y)
{
ULL res=1;
while(y)
{
if(y&1) (res*=x)%=YKH;
(x*=x)%=YKH,y>>=1;
}
return res;
}
int main()
{
read(n),read(m),n%=YKH;
register ULL i;ULL ans1=((n+m+1)%YKH*(n+m)%YKH)%YKH*(Inv(2,YKH-2)%YKH)%YKH,ans2=1,t=1;
for(i=n+1;i<n+m;++i) (ans2*=i%YKH)%=YKH;
for(i=2;i<m;++i) (ans2*=Inv(i%YKH,YKH-2))%=YKH;
for(i=n+1;i<=n+m;++i) (t*=i%YKH)%=YKH;
for(i=2;i<=m;++i) (t*=Inv(i%YKH,YKH-2))%=YKH;
(ans2*=5ll)%=YKH;
ULL ans=((ans1*ans2)%YKH*(Inv(t%YKH,YKH-2)%YKH))%YKH;
write((ans+5LL*(2LL*n%YKH+m+1)%YKH+YKH)%YKH);
return 0;
}
但是,我们会发现,这个代码会\(TLE\),只能得\(70\)分。怎么办呢?这时就要用卡常大法。
终于,在我的不懈努力下, 我改到了\(95\)分。代码如下:
#include<cstdio>
#include<cctype>
using namespace std;
unsigned long long n,m;
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(unsigned long long &x)
{
x=0;char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(unsigned long long x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline unsigned long long Inv(unsigned long long x,unsigned long long y)
{
unsigned long long res=1;
while(y)
{
if(y&1) (res*=x)%=998244853;
(x*=x)%=998244853,y>>=1;
}
return res;
}
int main()
{
read(n),read(m),n%=998244853;
register unsigned long long i;unsigned long long ans1=((n+m+1)%998244853*(n+m)%998244853)%998244853*(Inv(2,998244851)%998244853)%998244853,ans2=1,t=1,x;
for(i=n+1;i<n+m;++i) (ans2*=i)%=998244853,(t*=i)%=998244853;
for(i=2;i<m;++i) (ans2*=x=Inv(i,998244851))%=998244853,(t*=x)%=998244853;
(t*=(n+m)*(Inv(m,998244851))%998244853)%=998244853,(ans2+=ans2<<2)%=998244853;
unsigned long long ans=((ans1*ans2)%998244853*(Inv(t%998244853,998244851)%998244853))%998244853;
write((ans+(10*n%998244853+5*m+5)%998244853+998244853)%998244853);
return 0;
}
此时,我才发现,貌似是我的方法本身有问题。(虽然\(hl666\)跟我用同样的方法,他却AC了,大概是因为我天生自带大常数吧!)
冷静一会儿,我们便可以发现,原式可以转化为$$5(2A+B+1)+5B(A+B+1)$$即$$5AB+5B^2+10A+10B+5$$这样就可以快速求出答案了。(可惜我比赛时没想到)
代码如下:
#include<cstdio>
#include<cctype>
using namespace std;
unsigned long long n,m;
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(unsigned long long &x)
{
x=0;char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(unsigned long long x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline unsigned long long Inv(unsigned long long x,unsigned long long y)
{
unsigned long long res=1;
while(y)
{
if(y&1) (res*=x)%=998244853;
(x*=x)%=998244853,y>>=1;
}
return res;
}
int main()
{
read(n),read(m),n%=998244853;
register unsigned long long i;
unsigned long long ans=((n+m+1)*(n+m)%998244853*(Inv(2,998244851)%998244853)%998244853)*5%998244853;
unsigned long long res=ans*m%998244853*Inv(n+m,998244851)%998244853;
write((res+(10*n%998244853+5*m+5)%998244853+998244853)%998244853);
return 0;
}
【洛谷】CYJian的水题大赛 解题报告的更多相关文章
- CYJian的水题大赛
实在没忍住就去打比赛了然后一耗就是一天 最后Rank19还是挺好的(要不是乐多赛不然炸飞),这是唯一一套在Luogu上号称水题大赛的而实际上真的是水题大赛的比赛 好了我们开始看题 T1 八百标兵奔北坡 ...
- CYJian的水题大赛2 解题报告
这场比赛是前几天洛谷上 暮雪﹃紛紛dalao的个人公开赛,当时基本上都在水暴力分......也没有好好写正解(可能除了T1) 过了几天颓废的日子之后,本蒟蒻觉得应该卓越一下了qwq,所以就打算写一个解 ...
- [洛谷U22157]刷水题(数位dp)(hash)
题目背景 做正经题是不可能做正经题的,这辈子都不可能做正经题的,毒瘤题又不会做毒瘤题,就是水题这种东西,才维持了蒟蒻的信心: 题目描述 这里有N+1 道水题,编号分别为0 ~N+1 ,每道水题都有它自 ...
- 洛谷 P2323 [HNOI2006]公路修建问题 解题报告
P2323 [HNOI2006]公路修建问题 题目描述 输入输出格式 输入格式: 在实际评测时,将只会有m-1行公路 输出格式: 思路: 二分答案 然后把每条能加的大边都加上,然后加小边 但在洛谷的题 ...
- [POJ 1000] A+B Problem 经典水题 C++解题报告 JAVA解题报告
A+B Problem Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 311263 Accepted: 1713 ...
- 【洛谷】CYJian的水题大赛【第二弹】解题报告
点此进入比赛 T1: JerryC Loves Driving 第一题应该就是一道水分题(然而我只水了130分),我的主要做法就是暴力模拟,再做一些小小的优化(蠢得我自己都不想说了). My Code ...
- Mychael原创题 洛谷T23923 Mychaelの水题 【题解】
原题链接 题目大意: 有来自三个地区的人各a,b,c位,他们排成了一排.请问有多少种不同类型的排法,使得相邻的人都来自不同的地区 \(a,b,c<=200\) 答案取模 题解 弱弱的标程解法 设 ...
- [洛谷P4626]一道水题 II
题目大意:求$lcm(1,2,3,\cdots,n)\pmod{100000007}$,$n\leqslant10^8$ 题解:先线性筛出质数,然后求每个质数最多出现的次数,可以用$\log_in$来 ...
- 洛谷P1540 机器翻译 水题 模拟
注意一下细节,尤其是更新minv时不要更新错. Code: #include<vector> #include<iostream> #include<cstdio> ...
随机推荐
- python大战机器学习——数据预处理
数据预处理的常用流程: 1)去除唯一属性 2)处理缺失值 3)属性编码 4)数据标准化.正则化 5)特征选择 6)主成分分析 1.去除唯一属性 如id属性,是唯一属性,直接去除就好 2.处理缺失值 ( ...
- 高并发web系统优化总结
1.背景 因为业务需要,搭建了一个系统,系统主要由两部分组成,web页面和数据库. mysql大概2万条数据,其中有一个字段是click_num点击次数,php页面会取点击次数最小的一条记录去进行操作 ...
- Silverlight Telerik 学习之主题的设置
Telerik控件版本:RadControls for Silverlight Q1 2013 当前的Telerik Silverlight 控件支持以下主题 Office Black - 这是默认主 ...
- 修改apk里面的源码
1.解压apk文件,获取classes.dex并拷贝到资源根目录(使用zip或其他解压工具即可) 2.使用baksmali工具将classes.dex转为smali文件,在命令行定位到资源根目录并执行 ...
- gogs迁移
windows->linux 之前gogs放在windows server2016中,需要迁移至linux docker中. 首先拉取gogs镜像 docker pull gogs/gogs 然 ...
- 牛客网Java刷题知识点之构造函数与set方法、与类名同名的一般方法、构造函数中有return语句
不多说,直接上干货! 通过 牛客网Java刷题知识点之构造函数是什么.一般函数和构造函数什么区别呢.构造函数的重载.构造函数的内存图解 我们对构造函数有了一个比较清楚的认识,当我们在创建对象时,我们会 ...
- SpringBoot | 第十二章:RabbitMQ的集成和使用
前言 上节讲了缓存数据库redis的使用,在实际工作中,一般上在系统或者应用间通信或者进行异步通知(登录后发送短信或者邮件等)时,都会使用消息队列进行解决此业务场景的解耦问题.这章节讲解下消息队列Ra ...
- SpringBoot | 第一章:第一个SpringBoot应用
springboot简单介绍 概述 SpringBoot的核心功能 优缺点 优点 缺点 工程搭建 创建项目 项目结构 pom依赖 主入口 编写controller 启动应用 总结 老生常谈 sprin ...
- js 独立命名空间,私有成员和静态成员
独立的命名空间 1可以避免全局变量污染. 全局变量污染不是 说 被全局变量污染,而是说不会污染全局变量. 2实现私有成员. 在js中函数 就可以满足独立的命名空间的两点需求. 如: ...
- win10命令行压缩zip文件
1.下载winzip,下载winzip command line(官方) 2.使用命令 "C:\Program Files\WinZip\WZZIP.exe" C:\test\a. ...