GDOI2016模拟8.16打发时间
2015-08-17 08:58
274 查看
Luka再一次在化学课上发闷。这一次,他正在玩有智力的细菌。他把他的K只细菌放在一个长方形板上,这个板被分成N行从上到下标号1到N,M列从左到右标号1 到M。每个细菌一开始在一个特定的格子,面向周围4个格子的其中一个,每秒钟做以下的活动:
在当前所在的格子读入数字X给细菌。
顺时针旋转90度X次。
如果这个细菌面向板外,旋转180度。
最后移动到它面向的格子里。
Luka在某一个格子里装了一个陷阱。如果所有的细菌同一时刻进入这个格子,那么这个陷阱就会被激活,杀死所有的细菌。
因为Luka今天只有2小时的化学课,请你帮助他计算这个游戏会持续多少秒。
这题我们可以比较快的抓住题目的根本需求:
求出每个细菌路线的ρ图(一段没循环的,一段循环)然后(由于细菌比较少)就可以枚举在哪里为终点:
1、非循环部分直接暴力判断;
2、循环部分合并同余方程组(要都在循环里);
细节处理好就可以了。(还有一点,易证答案不会超过250042500^{4},所以不必担心溢出后,解同余方程组要用快速加、逆元什么的)
即便如此,我还是打了个取mod的但错了一个点…
如果有哪位大神能帮我看看取mod为什么会挂掉,我会很感激的:
取mod部分:
贴代码
在当前所在的格子读入数字X给细菌。
顺时针旋转90度X次。
如果这个细菌面向板外,旋转180度。
最后移动到它面向的格子里。
Luka在某一个格子里装了一个陷阱。如果所有的细菌同一时刻进入这个格子,那么这个陷阱就会被激活,杀死所有的细菌。
因为Luka今天只有2小时的化学课,请你帮助他计算这个游戏会持续多少秒。
这题我们可以比较快的抓住题目的根本需求:
求出每个细菌路线的ρ图(一段没循环的,一段循环)然后(由于细菌比较少)就可以枚举在哪里为终点:
1、非循环部分直接暴力判断;
2、循环部分合并同余方程组(要都在循环里);
细节处理好就可以了。(还有一点,易证答案不会超过250042500^{4},所以不必担心溢出后,解同余方程组要用快速加、逆元什么的)
即便如此,我还是打了个取mod的但错了一个点…
如果有哪位大神能帮我看看取mod为什么会挂掉,我会很感激的:
取mod部分:
long long calc(long long x,long long y,long long MOD){ if (!y)return 1; static long long s; s=calc(x,y/2,MOD); s=s*s%MOD; return (y&1)?s*x%MOD:s; } void extend_Euclid1(long long a, long long b) { static long long d,t; if(b==0) { x = 1; y = 0; return; } extend_Euclid1(b, a%b); t=x; x = y; y = t - a/b*y; } long long extend_Euclid(long long a, long long b,long long c) { static long long d,t; if(b==0) { x = c/a; y = 0; return a; } d=extend_Euclid(b, a%b,c); t=x; x = y; y = t - a/b*y; return d; } long long quick(long long x,long long y){ static long long s; s=0; while (y){ if (y&1)(s+=x)%=lcm; y/=2,(x+=x)%=lcm; } return s; } void getans(){ static long long d,e,gcd,c; d=1,e=0; for (int i=1;i<=k;i++){ gcd=extend_Euclid(d,ti[i],b[i]-e); c=ti[i]/gcd; x=(x%c+c)%c; e=(quick(d,x)+e)%lcm; extend_Euclid1(gcd,lcm); x=(x%lcm+lcm)%lcm; d=quick(quick(d,ti[i]),x); } for (int i=1;i<=k;i++){ while(e<b[i])e+=lcm; if ((e-b[i])%ti[i])return; } if (ans==-1)ans=e; else ans=min(ans,e); }
贴代码
#include<iostream> #include<algorithm> #include<cstdio> #define N 51 #include<cmath> using namespace std; int n,m,k,sum,sx,sy; long long ans,lcm,x,y,all; int help[4][2],a ,d ,pp ,ti ,b ,st ,f ; int map ,bz [4]; void dfs(int x,int y,int p,int z){ if (bz[x][y][p]==sum){ if (x==sx&&y==sy){ d[sum][++d[sum][0]]=z; pp[sum][d[sum][0]]=p; for (int i=d[sum][0]-1;;i--) if (pp[sum][i]==p){ ti[sum]=z-d[sum][i]; st[sum]=i; break; } return; } if (bz[sx][sy][0]!=sum&&bz[sx][sy][1]!=sum&&bz[sx][sy][2]!=sum&&bz[sx][sy][3]!=sum)return; } if (x==sx&&y==sy){ d[sum][++d[sum][0]]=z; pp[sum][d[sum][0]]=p; } bz[x][y][p]=sum; p=(p+map[x][y])%4; x+=help[p][0],y+=help[p][1]; if (!x||x>n||!y||y>m){ x-=help[p][0],y-=help[p][1]; p=(p+2)%4; x+=help[p][0],y+=help[p][1]; } dfs(x,y,p,z+1); } long long gcd(long long x,long long y){ if (!x) return y; return gcd(y%x,x); } void init(){ static int x,y,p; static char c; scanf("%d %d %d",&n,&m,&k); scanf("%d %d",&sx,&sy); lcm=all=1; for (int i=0;i<k;i++){ sum++; scanf("%d %d %c",&x,&y,&c); if (c=='U')p=0; else if (c=='R')p=1; else if (c=='D')p=2; else p=3; for (int j=1;j<=n;j++) for (int k=1;k<=m;k++) scanf(" %c",&c),map[j][k]=c-'0'; dfs(x,y,p,0); if (lcm) lcm=lcm/gcd(lcm,ti[sum])*ti[sum]; all*=ti[sum]; } } long long extend_Euclid(long long a, long long b,long long c) { static long long d,t; if(b==0) { x = c/a; y = 0; return a; } d=extend_Euclid(b, a%b,c); t=x; x = y; y = t - a/b*y; return d; } void getans(){ static long long d,e,gcd,c; d=1,e=0; for (int i=1;i<=k;i++){ gcd=extend_Euclid(d,ti[i],b[i]-e); c=ti[i]/gcd; x=(x%c+c)%c; e=d*x+e; d=d*ti[i]/gcd; } e%=lcm; for (int i=1;i<=k;i++){ while(e<f[i])e+=lcm; if ((e-f[i])%ti[i])return; } if (ans==-1)ans=e; else ans=min(ans,e); } void get(int x){ if (x>k){ getans(); return; } for (int i=st[x];i<=d[x][0];i++) b[x]=(f[x]=d[x][i])%ti[x],get(x+1); } void work(){ static bool p,p1; static int x; ans=-1,p1=1; for (int i=1;i<=k;i++){ for (int j=1;j<=d[i][0];j++){ for (int l=1;l<=k;l++) if (l!=i){ p=0; for (int r=1;!p&&r<=d[l][0];r++) if (d[i][j]==d[l][r])p=1; if (ti[l]) if (!p&&d[i][j]>d[l][d[l][0]]){ x=(d[i][j]-d[l][d[l][0]])%ti[l]; for (int r=st[l];!p&&r<d[l][0];r++) if (x==d[l][r]-d[l][st[l]]) p=1; } if (!p)break; } if (p){ if (ans==-1||ans>d[i][j])ans=d[i][j]; break; } } if (!ti[i])p1=0; } if (p1) get(1); } void write(){ if (ans==-1)printf("-1"); else printf("%lld",ans+1); } int main(){ help[0][0]=-1,help[1][1]=1,help[2][0]=1,help[3][1]=-1; init(); work(); write(); return 0; }
相关文章推荐
- 你把它列入博客设置?
- 【Ajax技术】JQuery处理XML数据
- Nginx服务器限制IP访问的各种情况全解析
- 通达OA 小飞鱼OA实施法:以项目管理的方式来推进工作流设计项目实施
- hdu 5391 Zball in Tina Town(威尔逊定理)
- 设置字符串中某些字符的特殊效果
- 通达OA 小飞鱼OA实施法:以项目管理的方式来推进工作流设计项目实施
- 普通程序猿的生存
- 线程小感
- 【零基础】CentOS 7 64位系统下编译Hadoop2.7.0
- hdu-5391 Zball in Tina Town 找规律(求素数)
- nyoj 14 会场安排问题
- 【bzoj3105】【cqoi2013】【新Nim游戏】【线性基+贪心】
- 利用ajax获取商品价格
- 08-13工作总结
- deeplearning库Caffe在windows下的配置
- Hard Code 4813
- HDOJ-1671-字典树
- TTL与RS-485电平转换芯片MAX485/MAX3485
- MAX13487E, MAX13488E半双工RS-485/RS-422收发器,带有自动选向控制