码迷,mamicode.com
首页 > 其他好文 > 详细

进攻幽暗城

时间:2017-07-03 20:01:46      阅读:318      评论:0      收藏:0      [点我收藏+]

标签:技术   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 }
View Code

 

进攻幽暗城

标签:技术   for   目标   空格   cpp   ems   i++   memset   数字串   

原文地址:http://www.cnblogs.com/whc200305/p/7112717.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!