标签:
题目在这里:http://acm.hdu.edu.cn/showproblem.php?pid=1175
大家都很熟悉的连连看,原理基本就是这个,典型的搜索.这里用的是广搜.
与普通的搜索比不同的是要求转折的线不能转折超过两次,就是在结构体中多开一个step(储存转折的次数)和一个dir(记录此刻的方向)
方向初始为-1,当行走一步后的方向与走之前不同的时候,step就应该加一,
然后还要注意的是为了保证得到的是所有的路线中转折次数最小的,这里的visit数组要用来保存每个点的最小转折次数,
所以初始化应该为很大
具体的看code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 #include<climits> 6 using namespace std; 7 int map[1005][1005],visit[1005][1005]; 8 struct point { 9 int x,y; 10 int step,dir;//记录转折次数与方向 11 } ; 12 int dx[4]={0,0,1,-1}; 13 int dy[4]={1,-1,0,0}; 14 int n,m,ex,ey; 15 int bfs(int sx,int sy) 16 { 17 int i; 18 queue<point>Q; 19 point next,now; 20 now.x=sx;now.y=sy; 21 now.step=0; 22 now.dir=-1; 23 Q.push(now); 24 while (!Q.empty()) 25 { 26 now=Q.front(); 27 Q.pop(); 28 if (now.x==ex&&now.y==ey) 29 return 1; 30 for (i=0;i<4;i++) 31 { 32 next.x=now.x+dx[i]; 33 next.y=now.y+dy[i]; 34 next.step=now.step; 35 next.dir=i; 36 if (next.dir!=now.dir&&now.dir!=-1)//方向发生变化就加一,但是是第一步的时候并不算是转折 37 next.step++; 38 if ((next.x<=n&&next.x>=1)&&(next.y<=m&&next.y>=1)&&(map[next.x][next.y]==0||(next.x==ex&&next.y==ey))) 39 { 40 if (next.step<3) 41 { 42 if (next.step<visit[next.x][next.y]) //让visit数组保存的是到每一点的最小转折次数 43 { 44 visit[next.x][next.y]=next.step; 45 Q.push(next); 46 } 47 } 48 } 49 } 50 } 51 return 0; 52 } 53 int main() 54 { 55 int i,j,t,sx,sy; 56 while (~scanf("%d %d",&n,&m)) 57 { 58 if (n==0&&m==0) 59 break; 60 for (i=1;i<=n;i++){ 61 for (j=1;j<=m;j++){ 62 scanf("%d",&map[i][j]); 63 } 64 } 65 scanf("%d",&t); 66 while (t--) 67 { 68 cin>>sx>>sy>>ex>>ey; 69 if (sx==ex&&sy==ey) 70 { 71 printf("NO\n"); 72 continue; 73 } 74 if (map[sx][sy]==0||map[ex][ey]==0||map[sx][sy]!=map[ex][ey])//这些特殊情况不要漏掉 75 { 76 printf("NO\n"); 77 continue; 78 } 79 for(i = 1; i <= n; i++) 80 for(j = 1; j <= m; j++) 81 visit[i][j] = 10000; //初始化为一个很大的数 82 if (bfs(sx,sy)==1) 83 printf("YES\n"); 84 else 85 printf("NO\n"); 86 } 87 88 } 89 return 0; 90 }
标签:
原文地址:http://www.cnblogs.com/JJCHEHEDA/p/4696944.html