Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10541 Accepted Submission(s): 3205
Special Judge
5 6 .XX.1. ..X.2. 2...X. ...XX. XXXXX. 5 6 .XX.1. ..X.2. 2...X. ...XX. XXXXX1 5 6 .XX... ..XX1. 2...X. ...XX. XXXXX.
It takes 13 seconds to reach the target position, let me show you the way. 1s:(0,0)->(1,0) 2s:(1,0)->(1,1) 3s:(1,1)->(2,1) 4s:(2,1)->(2,2) 5s:(2,2)->(2,3) 6s:(2,3)->(1,3) 7s:(1,3)->(1,4) 8s:FIGHT AT (1,4) 9s:FIGHT AT (1,4) 10s:(1,4)->(1,5) 11s:(1,5)->(2,5) 12s:(2,5)->(3,5) 13s:(3,5)->(4,5) FINISH It takes 14 seconds to reach the target position, let me show you the way. 1s:(0,0)->(1,0) 2s:(1,0)->(1,1) 3s:(1,1)->(2,1) 4s:(2,1)->(2,2) 5s:(2,2)->(2,3) 6s:(2,3)->(1,3) 7s:(1,3)->(1,4) 8s:FIGHT AT (1,4) 9s:FIGHT AT (1,4) 10s:(1,4)->(1,5) 11s:(1,5)->(2,5) 12s:(2,5)->(3,5) 13s:(3,5)->(4,5) 14s:FIGHT AT (4,5) FINISH God please help our poor hero. FINISH
1 #include <iostream>
2 #include <stdio.h>
3 #include <string.h>
4 using namespace std; 5 struct Way{ 6 int x; 7 int y; 8 bool ism; 9 }way[200]; //存储每一秒走到的位置,及有没有怪物
10 char maze[100][100]; 11 bool isv[100][100]; 12 int dx[4]={0,1,0,-1}; 13 int dy[4]={1,0,-1,0}; 14 int curx,cury; 15 int endx,endy; 16 int N,M; 17 int _min; 18 int dfs(int curx,int cury,int s) //当前的位置以及走到这个位置用的时间(秒)和方向
19 { 20 int n=0; 21 if(curx==N-1 && cury==M-1){ 22 //到达终点
23 _min=s; 24 if('1'<=maze[curx][cury] && maze[curx][cury]<='9'){ 25 //如果当前位置有怪物
26 int t; //怪物的HP
27 t=maze[curx][cury]-'0'; 28 for(int i=0;i<=t;i++){ 29 way[s-i].x=curx; 30 way[s-i].y=cury; 31 way[s-i].ism=true; 32 } 33 } 34 else{ 35 //当前位置没有怪物
36 way[s].x=curx; 37 way[s].y=cury; 38 way[s].ism=false; 39 } 40 return s; 41 } 42 //没有走到终点的时候
43 for(int i=0;i<4;i++){ 44 int nx = curx+dx[i]; 45 int ny = cury+dy[i]; 46 if(0<=nx && nx<=N-1 && 0<=ny && ny<=M-1 //如果没有越界
47 && maze[nx][ny]!='X' //下一步没有陷阱
48 && !isv[nx][ny] //下一步没走过
49 ){ 50 int t; //有怪物的话存储怪物的HP,否则为1
51 if('1'<=maze[nx][ny] && maze[nx][ny]<='9'){ 52 t=int(maze[nx][ny]-'0')+1; 53 } 54 else{ 55 t=1; 56 } 57 if(s+t>=_min) continue; //再次剪枝
58 isv[nx][ny]=true; 59 int tt; 60 if( tt=dfs(nx,ny,s+t) ){ 61 //找到最短路
62 n=tt; 63 way[s].x=curx; 64 way[s].y=cury; 65 way[s].ism=false; 66 if('1'<=maze[curx][cury] && maze[curx][cury]<='9'){ 67 //如果当前位置有怪物
68 int t; //怪物的HP
69 t=maze[curx][cury]-'0'; 70 for(int i=1;i<=t;i++){ 71 way[s-i].x=curx; 72 way[s-i].y=cury; 73 way[s-i].ism=true; 74 } 75 } 76 } 77 isv[nx][ny]=false; 78 } 79 } 80 return n; 81 } 82 int main() 83 { 84 while(scanf("%d%d",&N,&M)!=EOF){ //开始一个新的地图
85 getchar(); 86 memset(isv,0,sizeof(isv)); //初始化
87 _min=9999999; 88 curx=0,cury=0; //初始化开始、终点位置
89 endx=N-1,endy=M-1; 90 for(int i=0;i<N;i++){ 91 for(int j=0;j<M;j++){ 92 scanf("%c",&maze[i][j]); 93 } 94 getchar(); 95 } 96 int n; //如果能走到终点的话,接收最短步数
97 isv[0][0]=true; 98 n=dfs(curx,cury,0); 99 if(n){ 100 //能走
101 printf("It takes %d seconds to reach the target position, let me show you the way.\n",n); 102 for(int i=0;i<n;i++){ 103 if(way[i].ism){ 104 //如果有怪物
105 printf("%ds:FIGHT AT (%d,%d)\n",i+1,way[i].x,way[i].y); 106 } 107 else { 108 printf("%ds:(%d,%d)->(%d,%d)\n",i+1,way[i].x,way[i].y,way[i+1].x,way[i+1].y); 109 } 110 } 111 } 112 else{ 113 //走不到终点
114 printf("God please help our poor hero.\n"); 115 } 116 printf("FINISH\n"); 117 } 118 return 0; 119 }
1 #include <iostream>
2 #include <string.h>
3 #include <queue>
4 using namespace std; 5 char a[101][101]; //记录地图
6 char b[101][101]; //备用地图,用以修改
7 int isv[101][101]; //记录访问过没有
8 int way[101][101]; //记录路径
9 int dx[4] = {0,1,0,-1}; 10 int dy[4] = {1,0,-1,0}; 11 int N,M; 12 struct NODE{ 13 int x; 14 int y; 15 int step; 16 }; 17 bool judge(int x,int y) 18 { 19 if( x<1 || y<1 || x>N || y>M ) //出界
20 return 1; 21 if( isv[x][y] ) //走过
22 return 1; 23 if( a[x][y]=='X' ) //遇到墙
24 return 1; 25 return 0; 26 } 27 int bfs(int x,int y) //返回到达终点的时间(包括在终点停留的时间)
28 { 29 for(int i=1;i<=N;i++) 30 for(int j=1;j<=M;j++) 31 b[i][j] = a[i][j]; 32 queue <NODE> q; 33 NODE cur,next; 34 cur.x = x; 35 cur.y = y; 36 cur.step = 0; 37 q.push(cur); //第一个节点入队
38 while(!q.empty()){ 39 cur = q.front(); 40 q.pop(); //队首出队
41 if( cur.x==N && cur.y==M ){ 42 int num = 0; 43 if('1'<=b[cur.x][cur.y] && b[cur.x][cur.y]<='9') 44 num = b[cur.x][cur.y] - '0'; 45 return cur.step + num; 46 } 47 if('1'<=b[cur.x][cur.y] && b[cur.x][cur.y]<='9'){ //遇到怪物,step+1,位置不变,入队
48 next.x = cur.x; 49 next.y = cur.y; 50 next.step = cur.step + 1; 51 q.push(next); 52 if(b[cur.x][cur.y]=='1') 53 b[cur.x][cur.y] = '.'; 54 b[cur.x][cur.y]--; 55 continue; 56 } 57 for(int i=0;i<4;i++){ 58 int nx = cur.x + dx[i]; 59 int ny = cur.y + dy[i]; 60 if(judge(nx,ny)) //判定
61 continue; 62 //可以走
63 next.x = nx; 64 next.y = ny; 65 way[nx][ny] = i; //记录路径
66 isv[nx][ny] = true; //记录访问过
67 next.step = cur.step + 1; 68 q.push(next); 69 } 70 } 71 return 0; 72 } 73 int main() 74 { 75 while(cin>>N>>M){ 76 for(int i=1;i<=N;i++) 77 for(int j=1;j<=M;j++) 78 cin>>a[i][j]; 79 memset(isv,0,sizeof(isv)); 80 isv[1][1] = true; 81 int step = bfs(1,1); 82 if(step){ //到达终点
83 NODE way_node[10001]; 84 int cx=N,cy=M; 85 for(int i=step;i>=0;i--){ //根据way[][]还原路径
86 way_node[i].x = cx; 87 way_node[i].y = cy; 88 int num=0; 89 if('1'<=a[cx][cy] && a[cx][cy]<='9') //如果该位置有怪物
90 num = a[cx][cy] - '0'; 91 for(int j=num;j>=1;j--){ 92 way_node[i-j].x = cx; 93 way_node[i-j].y = cy; 94 } 95 if(num){ 96 i-=num; 97 } 98 switch(way[cx][cy]){ //没有怪物则继续还原路径
99 case 0:cy--;break; 100 case 1:cx--;break; 101 case 2:cy++;break; 102 case 3:cx++;break; 103 default:break; 104 } 105 } 106 //输出结果
107 cout<<"It takes "<<step<<" seconds to reach the target position, let me show you the way."<<endl; 108 for(int i=1;i<=step;i++){ 109 cout<<i<<"s:("<<way_node[i-1].x-1<<','<<way_node[i-1].y-1<<")->("<<way_node[i].x-1<<','<<way_node[i].y-1<<')'<<endl; 110 cx = way_node[i].x; 111 cy = way_node[i].y; 112 if('1'<=a[cx][cy] && a[cx][cy]<='9'){ 113 int num = a[cx][cy] - '0'; 114 for(int j=1;j<=num;j++) 115 cout<<i+j<<"s:FIGHT AT ("<<way_node[i].x-1<<','<<way_node[i].y-1<<')'<<endl; 116 i += num; 117 } 118 } 119 cout<<"FINISH"<<endl; 120 } 121 else{ //没有到达终点
122 cout<<"God please help our poor hero."<<endl; 123 cout<<"FINISH"<<endl; 124 } 125 } 126 return 0; 127 }
受同学启发,用“优先队列”又写了一遍,顺便学习了一下优先队列的使用。
思路和上面是基本相同的,只不过遇到怪物时的处理用优先队列简化了许多,优先队列不会用的筒靴可以参考下面的链接:
另外给出一位同样用优先队列实现的博客链接,不过人家是0MS AC,我是31MS AC,有差距啊!
下面是我用优先队列做的代码:
1 #include <iostream>
2 #include <string.h>
3 #include <queue>
4 using namespace std; 5 char a[101][101]; 6 char isv[101][101]; //记录访问过没有
7 int dir[101][101]; //记录每一个节点的来路方向,即整个地图遍历的顺序
8 int dx[4] = {0,1,0,-1}; 9 int dy[4] = {1,0,-1,0}; 10 int N,M; 11 struct NODE{ 12 int x; 13 int y; 14 int step; 15 friend bool operator < (NODE n1,NODE n2) //自定义优先级。在优先队列中,优先级高的元素先出队列。
16 { 17 return n1.step > n2.step; //通过题意可知 step 小的优先级高,需要先出队。
18 } 19 }; 20 bool judge(int x,int y) 21 { 22 if( x<1 || y<1 || x>N || y>M ) 23 return 1; 24 if( isv[x][y] ) 25 return 1; 26 if( a[x][y]=='X' ) 27 return 1; 28 return 0; 29 } 30 int bfs(int x,int y) //返回从(x,y)开始广搜,到右下角的最短步数,如果无法到达右下角,返回0
31 { 32 priority_queue <NODE> q; //定义一个优先队列
33 NODE cur,next; 34 cur.x = x; 35 cur.y = y; 36 cur.step = 0; 37 q.push(cur); //第一个元素入队
38 while(!q.empty()){ 39 cur = q.top(); //队首出队,注意不是front()
40 q.pop(); 41 if(cur.x==N && cur.y==M){ //到终点
42 return cur.step; 43 } 44 for(int i=0;i<4;i++){ 45 int nx = cur.x + dx[i]; 46 int ny = cur.y + dy[i]; 47 if( judge(nx,ny) ) //判定
48 continue; 49 //可以走
50 next.x = nx; 51 next.y = ny; 52 isv[nx][ny] = true; 53 dir[nx][ny] = i; 54 if( '1'<=a[nx][ny] && a[nx][ny]<='9' ){ //这一步有怪物
55 int hp = a[nx][ny] - '0'; 56 next.step = cur.step + hp + 1; 57 } 58 else //这一步没有怪物
59 next.step = cur.step + 1; 60 q.push(next); 61 } 62 } 63 return 0; 64 } 65 int main() 66 { 67 while(cin>>N>>M){ 68 for(int i=1;i<=N;i++) 69 for(int j=1;j<=M;j++) 70 cin>>a[i][j]; 71 memset(isv,0,sizeof(isv)); 72 isv[1][1] = true; 73 int step = bfs(1,1); 74 if(step){ //step有值,能够到达终点 75 //还原路径
76 NODE way[10001]; 77 int cx=N,cy=M; 78 for(int i=step;i>=0;i--){ 79 way[i].x = cx; 80 way[i].y = cy; 81 if('1'<=a[cx][cy] && a[cx][cy]<='9'){ //当前位置有怪物
82 int hp = a[cx][cy] - '0'; 83 for(int j=1;j<=hp;j++){ 84 way[i-j].x = cx; 85 way[i-j].y = cy; 86 } 87 i -= hp; 88 } 89 switch(dir[cx][cy]){ 90 case 0:cy--;break; 91 case 1:cx--;break; 92 case 2:cy++;break; 93 case 3:cx++;break; 94 default:break; 95 } 96 } 97 //输出结果
98 cout<<"It takes "<<step<<" seconds to reach the target position, let me show you the way."<<endl; 99 for(int i = 1;i<=step;i++){ 100 cout<<i<<"s:("<<way[i-1].x-1<<','<<way[i-1].y-1<<")->("<<way[i].x-1<<','<<way[i].y-1<<')'<<endl; 101 if( '1'<=a[way[i].x][way[i].y] && a[way[i].x][way[i].y]<='9' ){ //如果有怪物
102 int hp = a[way[i].x][way[i].y] - '0'; 103 for(int j=1;j<=hp;j++) 104 cout<<i+j<<"s:FIGHT AT ("<<way[i+j].x-1<<','<<way[i+j].y-1<<')'<<endl; 105 i+=hp; 106 } 107 } 108 } 109 else{ //step为0,说明不能到达终点
110 cout<<"God please help our poor hero."<<endl; 111 } 112 cout<<"FINISH"<<endl; 113 } 114 return 0; 115 }
Freecode : www.cnblogs.com/yym2013