[JZOJ3507] 游乐场
来源:互联网 发布:大学生交通事故数据 编辑:程序博客网 时间:2024/04/28 06:27
Description
今天是个好日子,小A和他的小伙伴们一起去逛游乐园。这时,游乐园中忽然出现了一个伪装的吸血鬼,小A和他的小伙伴们都惊呆了!小伙伴们马上跑向了游乐园的四面八方。当“吸血鬼”回家吃饭的时候,小A才发现他已经和他的小伙伴们走散了。小A是个路痴,所以他只好站在原地等小伙伴们回来。
我们可以将游乐园视为一个N行M列的矩形,最上面一行为第1行,最左边一列为第1列。每个小伙伴手里都有一张神奇的地图,地图中对应着游乐园的每行每列都有一个写着0-9中某个数字的路标。小A的K位小伙伴们每一秒都会依次进行以下行动:
读取他所在的位置上的路标X;
顺时针旋转90度X次;
如果他面对游乐园外,那就他会再转180度;
移动到他面对的位置。
小A的视力很糟糕。只有当所有的小伙伴都同时出现在他所在的位置时,他才能和他的小伙伴们团聚。小A等得很心急,所以他求助于你。请你告诉他,他和小伙伴们团聚所需要的时间。
对于100%的数据,3<=N, M<=50,1<=K<=5如果小A和他的小伙伴们能够团聚,团聚的总秒数小于10^18。
Solution
显然我们需要找循环节。
首先将每个点拆成四个状态,从不同方向进入。
先考虑在环内。
根据环中到达小A点的状态,可以列出方程组。
X表示第一次在环中到这个状态的时间,Y表示环的长度。
那就是
对于同一个人可能在环中从不同方向经过目标点,那么就枚举选哪一个。
现在要解最小的T
观察
合并后的式子就是
完全可以暴力解,枚举
一条条合并,到最后的A就是答案,因为我们要T最小。
然后再看环以外的,用个标记桶存起来,特判即可。
Code
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)#define LL long long#define N 55 using namespace std;int map[N][N],n,m,l,xt,yt,fr[6][3],fx[4][2]={{-1,0},{0,1},{1,0},{0,-1}},d[9][2],rx,bz[4*N*N],num[6],b1[N][N][4];LL fc1[6][2],ans,fc[6][5][2],ti,s[4][2];LL gcd(LL x,LL y){ LL r=y; while(r!=0) r=x%y,x=y,y=r; return x;}void find(int x,int y,int f,int dis){ while(b1[x][y][f]<2) { b1[x][y][f]++; if(x==xt&&y==yt) { d[++d[0][0]][0]=dis; d[d[0][0]][1]=f; if(s[f][0]==0) s[f][0]=dis; else if(s[f][1]==0) { if(rx==-1) rx=d[0][0]; s[f][1]=dis; ti=s[f][1]-s[f][0]; } else { d[0][0]--; return; } } f=(f+map[x][y])%4; LL x2=x+fx[f][0],y2=y+fx[f][1]; if(x2<1||x2>n||y2<1||y2>m) f=(f+2)%4; x2=x+fx[f][0],y2=y+fx[f][1]; x=x2,y=y2; dis++; }}void dfs(int i){ if(i>l) { if(fc1[l][1]<ans||ans==-1) ans=fc1[l][1]; return; } fo(j,1,num[i]) { fc1[i][0]=fc[i][j][0]; fc1[i][1]=fc[i][j][1]; if(i==1) { dfs(i+1); continue; } LL p=fc1[i][0]/gcd(fc1[i][0],fc1[i-1][0]),v=fc1[i-1][1]; if(v%fc1[i][0]==fc1[i][1]%fc1[i][0]&&v>=fc1[i][1]) fc1[i][0]=p*fc1[i-1][0],fc1[i][1]=v,dfs(i+1); else { fo(k,1,p) { v+=fc1[i-1][0]; if(v%fc1[i][0]==fc1[i][1]%fc1[i][0]&&v>=fc1[i][1]) break; } if(v%fc1[i][0]==fc1[i][1]%fc1[i][0]&&v>=fc1[i][1]) fc1[i][0]=p*fc1[i-1][0],fc1[i][1]=v,dfs(i+1); } }}int main(){ cin>>n>>m>>l; cin>>xt>>yt; fo(i,1,4*N-1) bz[i]=1; bool pd=0; fo(i,1,l) { scanf("%d%d",&fr[i][0],&fr[i][1]); char ch; scanf("%c",&ch); scanf("%c",&ch); if(ch=='U') fr[i][2]=0; if(ch=='R') fr[i][2]=1; if(ch=='D') fr[i][2]=2; if(ch=='L') fr[i][2]=3; fo(j,1,n) { scanf("\n"); fo(k,1,m) { char ch; scanf("%c",&ch); map[j][k]=(ch-'0')%4; } } memset(s,0,sizeof(s)); memset(d,255,sizeof(d)); d[0][0]=0; rx=-1; memset(b1,0,sizeof(b1)); find(fr[i][0],fr[i][1],fr[i][2],1); if(d[0][0]==0) { printf("-1\n"); return 0; } if(rx==-1) { fo(i,1,d[0][0]) bz[d[i][0]]++; pd=1; } else { fo(j,1,d[0][0]) bz[d[j][0]]++; LL p=d[d[0][0]][0]+ti; fo(j,rx,d[0][0]) { num[i]++; while(p<=4*n*m) { bz[p]++; p+=ti; } fc[i][num[i]][0]=ti; fc[i][num[i]][1]=s[d[j][1]][0]; } } } int fs=-1; fo(i,1,4*n*m) { if(bz[i]==l&&fs!=-1) { fs=i; break; } } if(pd) printf("%d\n",fs); else { ans=-1; dfs(1); if(fs=-1||ans<fs) printf("%lld\n",ans); else printf("%d\n",fs); }}
0 0
- [JZOJ3507] 游乐场
- 游乐场
- hdu 游乐场
- Tensorflow游乐场
- 最佳的代码游乐场
- 杭电校赛(游乐场)
- vijosP1471 教主的游乐场
- google Tensorflow游乐场
- [vijos1471] 教主的游乐场
- Tensorflow playground(Tensorflow游乐场)
- 数学+图论 建造游乐场
- Vijos 1471 教主的游乐场
- 系统性能估算游乐场模型
- 游乐场 ssl1776 双连通分量
- JZOJ 1407. 教主的游乐场
- vijos 1471 教主的游乐场
- tensorflow 实现游乐场的网络
- [vijos 1471]教主的游乐场
- 让linux find命令查询的结果为绝对路径
- ZOJ3324-Machine
- esri-leaflet部分瓦片缺失问题及解决办法
- hashcode与equals 总结
- 运营喵工作中常犯的错误有哪几类?
- [JZOJ3507] 游乐场
- android
- ssh note
- 先序,中序建立二叉树
- nginx启用浏览目录功能
- VisualAssist工具中Snippet的导入导出
- 数据结构中利用栈计算算术表达式
- 谷哥的小弟学后台(11)——Servlet(3)
- MySql的count函数的用法简解