标签:技术 for 目标 空格 cpp ems i++ memset 数字串
进攻幽暗城
(attack.pas/c/cpp)
【问题描述】
由于震惊海内外的“愤怒门投毒事件”的发生,部落为了对抗皇家药剂师协会的叛乱,所有的外交
工作完成后,部落大酋长萨尔带领着小A 穿过传送门到达幽暗城平叛。
幽暗城的地图是一个N*M 的 01 串。a[i,j]=1 时表示(i,j)的位置是障碍,无法通过;a[i,j]=0 时
表示(i,j)的位置可以进入。
小 A 与萨尔的初始位置是(x1,y1),而恐惧魔王的初始位置是(x2,y2)。小 A 的目标就是到达恐惧魔
王的位置。
萨尔会按照一个特定的路线行走,该路线是一个数字串,由 0-4组成。第i 秒,若数字串第(i mod
数字串的长度)位=0,则表示这一秒萨尔将会原地不动;=1,则表示这一秒萨尔会向上走一格;=2,则
表示这一秒萨尔会向下走一格;=3,则表示这一秒萨尔会向左走一格;=4,则表示这一秒萨尔会向右走
一格。若萨尔将要移动的位置是墙或者超出迷宫的范围,则萨尔会原地不动。恐惧魔王也是这样。(换
句话说,你可以认为如果将数字串是重复无限次,第 i 秒就是字符串第i 位)
小A 每秒可以选择从上下左右四个方向中选择一个方向,朝那个方向走一格,前提是那个位置不是
墙并且没有超出迷宫的范围;或者原地不动。不过,由于幽暗城的诡异环境,小 A 只能持续脱离萨尔的
光环 s 秒,若超过 s 秒小 A 则会死亡。光环的有效半径为 d,表示当小 A 与萨尔之间的距离
√(x ? xx)2 + (y ? yy)2,小于等于 d 时小 A 才能受到萨尔光环的效果。若小 A 脱离萨尔的光环又重新
进入光环有效区域,则再次离开光环时持续时间归零重记。
小A 想知道最少需要几秒他才能到达恐惧魔王所在的位置。
【输入格式】
第一行四个数N,M,s,d。
接下来的N 行,每行M 个数(0或1),之间没有空格,表示幽暗城的地图。
接下来的一行四个整数,x1,y1,x2,y2(1≤x1,x2≤N,1≤y1,y2≤M)。
接下来的一行是一个数字串,表示萨尔的移动方式。
接下来的一行是一个数字串,表示恐惧魔王的移动方式。
【输出格式】
输出共一行一个整数,表示需要最少的时间。
【输入样例】
3 4 7 3
1010
0000
0101
1 2 3 3
0132401
12131
【输出样例】
3
【数据规模】
对于100%的数据:1≤N,M≤50;0≤s≤1000;0≤d≤100;1≤数字串长度≤1,000;0≤答案≤100。
这个图论很诡异喂,终点居然可以动,更可恶的是还有那什么什么破光环,还有限制,真 是气史宝宝了。其实,这题由于数据较小,还是能杀下来 滴。。首先,我们要把魔王和萨尔的行踪记录下来。难点 主要在于光环处。当然,如果没有光环限制,无论刷bfs还 是spfa都能搞定。那么有光环也差不多。那么,我们用dst [x][y][t]表示当前处于x,y,并且已经走了t秒,此时脱离光环 的时间。那么,我们要判断的是什么呢?我们无非不能小A脱离光环超过s秒。那么,只要满足了 dst[tx][ty][t+1]<=s就行了。tx,ty是当前将要走到的位置 当然,判断前还要更新 dst[tx][ty][t+1]:=check(dst[x][y][t],tx,ty,t+1);当然,这 是在dst[tx][ty][t+1]>check(dst[x][y][t],tx,ty,t+1)的情况 下更新的。check(num,x,y,t)怎么写?只要在光环里就行了。 if sqr(x-pos_sa[t].x)+sqr(y-pos_sa[t].y)<=sqr(d) then exit(0) else exit(num+1);如果回到光环内,那么时 间清0,否则继续。更新好后是否入队呢?不一定,仅当 (vis[tx][ty][t+1]) or (dst[tx][ty][t+1]>s)这个状态没走过 时或者小A在这种情况下没死时,入队。那么,可以刷bfs 也可以刷spfa。那么,当某次小A的坐标等于魔王的坐标时 把时间输出就好了啊。o_O
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #define sqr(x) ((x)*(x)) 6 using namespace std; 7 const int maxn=55,maxt=105,maxv=55*55*105,fl[5][2]={{0,0},{-1,0},{1,0},{0,-1},{0,1}}; 8 char sa[maxt],mo[maxt]; 9 bool vis[maxn][maxn][maxt]; 10 int n,m,s,d; 11 int grp[maxn][maxn],dst[maxn][maxn][maxt]; 12 int x_sa,y_sa,l_sa,x_mo,y_mo,l_mo,x_a,y_a; 13 int x1,y1,x2,y2,tx,ty; 14 int hd,tl; 15 struct data{ 16 int x,y,t; 17 }p_sa[maxt],p_mo[maxt],qu[maxv]; 18 19 void _init(){ 20 scanf("%d%d%d%d",&n,&m,&s,&d); 21 char ch; 22 for (int i=1; i<=n; i++){ 23 int x=0; 24 while (x<m){ 25 x++; ch=getchar(); 26 while (ch<‘0‘||ch>‘1‘) ch=getchar(); 27 grp[i][x]=(ch==‘1‘); 28 } 29 } 30 memset(sa,0,sizeof(sa)); 31 memset(mo,0,sizeof(mo)); 32 scanf("%d%d%d%d",&x_sa,&y_sa,&x_mo,&y_mo); x_a=x_sa,y_a=y_sa; 33 ch=getchar(); 34 while (ch<‘0‘||ch>‘4‘) ch=getchar(); 35 while (ch>=‘0‘&&ch<=‘4‘) sa[++l_sa]=ch,ch=getchar(); 36 ch=getchar(); 37 while (ch<‘0‘||ch>‘4‘) ch=getchar(); 38 while (ch>=‘0‘&&ch<=‘4‘) mo[++l_mo]=ch,ch=getchar(); 39 } 40 void write(int ans){ 41 printf("%d",ans); exit(0); 42 } 43 bool chk_rg(int x,int y){ 44 if (x<1||x>n||y<1||y>m) return false; 45 return grp[x][y]==0; 46 } 47 int chk_tm(int now,int x,int y,int t){ 48 if (sqr(x-p_sa[t].x)+sqr(y-p_sa[t].y)<=sqr(d)) return 0; else return now+1; 49 } 50 void _move(int nowt){ 51 tx=x1+fl[sa[((nowt-1)%l_sa)+1]-‘0‘][0],ty=y1+fl[sa[((nowt-1)%l_sa)+1]-‘0‘][1]; 52 if (chk_rg(tx,ty)) { x1=tx,y1=ty; } 53 tx=x2+fl[mo[((nowt-1)%l_mo)+1]-‘0‘][0],ty=y2+fl[mo[((nowt-1)%l_mo)+1]-‘0‘][1]; 54 if (chk_rg(tx,ty)) { x2=tx,y2=ty; } 55 p_sa[nowt]={x1,y1,0},p_mo[nowt]={x2,y2,0}; 56 } 57 void _spfa(){ 58 memset(vis,0,sizeof(vis)); 59 memset(dst,63,sizeof(dst)); 60 dst[x_a][y_a][0]=0; vis[x_a][y_a][0]=1; 61 hd=0; tl=1; qu[1]={x_a,y_a,0}; 62 while (hd!=tl){ 63 hd=(hd+1)%maxv; int x=qu[hd].x,y=qu[hd].y,t=qu[hd].t; vis[x][y][t]=0; 64 if (x==p_mo[t].x&&y==p_mo[t].y) write(t); 65 for (int i=0; i<=4; i++){ 66 tx=x+fl[i][0],ty=y+fl[i][1]; 67 if (!chk_rg(tx,ty)) continue; 68 int t_need=chk_tm(dst[x][y][t],tx,ty,t+1); 69 if (dst[tx][ty][t+1]<=t_need) continue; 70 dst[tx][ty][t+1]=t_need; 71 if (vis[tx][ty][t+1]||dst[tx][ty][t+1]>s) continue; 72 tl=(tl+1)%maxv; qu[tl]={tx,ty,t+1}; vis[tx][ty][t+1]=1; 73 } 74 } 75 } 76 void _work(){ 77 x1=x_sa,y1=y_sa,x2=x_mo,y2=y_mo; 78 p_sa[0]={x1,y1,0}; p_mo[0]={x2,y2,0}; 79 for (int i=1; i<=100; i++) _move(i); 80 _spfa(); 81 } 82 int main(){ 83 _init(); 84 _work(); 85 return 0; 86 }
标签:技术 for 目标 空格 cpp ems i++ memset 数字串
原文地址:http://www.cnblogs.com/whc200305/p/7112717.html