POJ-3009 深度优先搜索
2017-06-08 20:59
501 查看
关于这道题,考的依旧是深度优先搜索。。我没有写出来,但参考了网上的一些答案。总共两个版本。其中一个版本我怎么写都不对,实在看不出哪里有错,恳请牛人指出。
第一个版本:(求纠错!!)
这是我写的:
#include <iostream> #include <cstdio> #define MAX_N 30 #define MAX 99999999 using namespace std; int field[MAX_N][MAX_N]; int n,m; //m行n列 int sx,sy,gx,gy; //起点和终点的坐标 int dx[4] = {1,-1,0,0}; int dy[4] = {0,0,1,-1}; int step,result; void dfs(int x ,int y){ int px,py; if(step >= 10){ return; } for(int i = 0;i<4;i++){ px = x; py = y; while(1){ px += dx[i]; py += dy[i]; if(px<=0 || px > n || py<=0 || py>m) break; //越界,选择其他方向 if(px == gx && py == gy){ step++; if(result > step) result = step; step--; return; }else if(field[px][py] == 1){ if(px-dx[i] != sx || py-dy[i] != sy){ step++; field[px][py] = 0; dfs(px-dx[i],py-dy[i]); field[px][py] = 1; //回溯 step--; //恢复步数 } break; } } } } int main() { freopen("D:/OJ/挑战程序设计竞赛/冰球.txt","r",stdin); while((cin>>m>>n) && (m || n)){ for(int i = 1;i<=n;i++) for(int j = 1;j<=m;j++){ cin>>field[i][j]; if(field[i][j] == 2){ sx = i; sy = j; }else if(field[i][j] == 3){ gx = i; gy = j; } } result = MAX; step = 0; dfs(sx,sy); if(result == MAX){ cout<<-1<<endl; }else{ cout<<result<<endl; } } return 0; }
这是借鉴的答案:原版答案
#include<stdio.h> int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int ei,ej; int map[25][25]; int w,h,steps,min; #define MAX 99999999 void dfs(int si,int sj) { int i,pi,pj; if(steps>=10) return ; for(i=0;i<4;i++) { pi=si,pj=sj; while(1) { pi+=dir[i][0]; pj+=dir[i][1]; if(pi<=0||pi>h||pj<=0||pj>w) break;//如果越界,选择其他方向 if(pi==ei&&pj==ej) { steps++; if(min>steps) min=steps; steps--; return; } else if(map[pi][pj]==1)//如果遇到障碍物 { if(pi-dir[i][0]!=si||pj-dir[i][1]!=sj)//如果不是起来 { map[pi][pj]=0;//消除障碍物 steps++;//前进一步 dfs(pi-dir[i][0],pj-dir[i][1]);//递归查找该点到终点的最小步数 map[pi][pj]=1;//还原障碍物 steps--;//还原步数 } break; } } } } int main() { freopen("D:/OJ/挑战程序设计竞赛/冰球.txt","r",stdin); int si,sj,i,j; while(scanf("%d%d",&w,&h)==2&&(w||h)) { for(i=1;i<=h;i++)//输入并找到起点和终点 for(j=1;j<=w;j++) { scanf("%d",&map[i][j]); if(map[i][j]==2) si=i,sj=j; else if(map[i][j]==3) ei=i,ej=j; } min=MAX;//记录最小步数 steps=0;//初始化步数 dfs(si,sj);//深搜 if(min==MAX) puts("-1"); else printf("%d\n",min); } return 0; }
第二个版本:(客户端结果正确,但不知道为什么提交时确是WA)
#include <iostream> #include <cstdio> #define MAX_N 30 using namespace std; struct Info{ int field[MAX_N][MAX_N]; int x,y; }; int n,m; //m行n列 int sx,sy,gx,gy; //起点和终点的坐标 int dx[4] = {1,0,-1,0}; int dy[4] = {0,1,0,-1}; int step; void dfs(Info info,int k){ if(k>=step){ return; } //向下查找 //首先判断如果x+1是否会越界 以及 该处不是障碍物 if(info.x+1 < n && info.field[info.x+1][info.y] != 1){ for(int i = 1;info.x+i<n;i++){ //查找该直线上是否有障碍物 if(info.field[info.x+i][info.y] == 1){ //查找到障碍物 Info info2 = info; //定义一个新的Info节点,该节点的障碍物为将被清掉 info2.field[info.x+1][info.y] = 0; //清掉该障碍物 info2.x = info.x+i-1; //并将该节点的位置退一步 dfs(info2,k+1); //深度优先搜索 break; } if(info.field[info.x+i-1][info.y] == 3){//如果该位置为终点 if(step>k+1){ //判断该位置所走的步数是否为最优的步数 step = k+1; //不是最优的话将会被替换 } return; } } } //向上查找 具体分析如上 if(info.x-1>=0 && info.field[info.x-1][info.y] != 1 ){ for(int i = 1;info.x-i>=0;i++){ if(info.field[info.x-i][info.y] == 1){ Info info2 = info; info2.field[info.x-i][info.y] = 0; info2.x = info.x-i+1; dfs(info2,k+1); break; } if(info.field[info.x-i][info.y] == 3){ if(step>k+1){ step = k+1; } return; } } } //向右查找 if(info.y+1<m && info.field[info.x][info.y+1] != 1){ for(int i = 1;i+info.y<m;i++){ if(info.field[info.x][info.y+i] == 1){ Info info2 = info; info2.field[info.x][info.y+i] = 0; info2.y = info.y+i-1; dfs(info2,k+1); break; } if(info.field[info.x][info.y+i] == 3){ if(step>k+1){ step = k+1; } return; } } } //向左查找 if(info.y-1>=0 && info.field[info.x][info.y-1] != 1){ for(int i = 1;info.y-i>=0;i++){ if(info.field[info.x][info.y-i] == 1){ Info info2 = info; info2.field[info.x][info.y-i] = 0; info2.y = info.y-i+1; dfs(info2,k+1); break; } if(info.field[info.x][info.y-i] == 3){ if(step>k+1){ step = k+1; } return; } } } } int main() { freopen("D:/OJ/挑战程序设计竞赛/冰球.txt","r",stdin); while((cin>>m>>n) && m!=0){ Info info; for(int i = 0;i<n;i++){ for(int j = 0;j<m;j++){ cin>>info.field[i][j]; if(info.field[i][j] == 2){ info.x = i; info.y = j; } } } step = 11; dfs(info,0); if(step == 11){ cout<<-1<<endl; }else{ cout<<step<<endl; } } }
相关文章推荐
- poj3009之深度优先搜索 dfs解法
- 深度优先搜索【POJ 3009】
- POJ3009 - Curling 2.0 - 深度优先搜索
- POJ1321,深度优先搜索
- POJ 1008 深度优先、记忆搜索
- poj 3009(深度搜索)
- 深度优先搜索【POJ 1979】
- ACM-POJ 1562 DFS 深度优先搜索
- POJ-1979 深度优先搜索DFS
- POJ1426-Find The Multiple-深度优先搜索BFS
- POJ-2386-Lake Counting(深度优先搜索初步!)
- POJ-2488 A Knights Journey-深度优先搜索DFS
- 20124330102 【 搜索 -- 深度优先搜索 】 POJ 3414 Pots
- 挑战第二章习题 POJ 1974 深度优先搜索
- Late Counting (POJ 2386) 深度优先搜索
- poj1088 滑雪 dp记忆化搜索 dfs深度优先搜索
- 深度优先搜索dfs(poj 1655)
- POJ 1979 深度优先搜索
- POJ1562 - Oil Deposits - 深度优先搜索
- 深度优先搜索 poj 2386