HDU-1175-连连看
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1175
程序分析:
题意大概就是说了一些连连看的游戏规则,就是在有限次转弯内能到达终点而且两个点是同样的类型的点就可以把他们消去。注意的是不可以绕过外面而相连,而且两个点不可以存在是0类型的点,也不可以是始点跟终点为相同的一个点。给你整张图,还有一些点,问你这些点能否消去。
解决方法:
要求最小的弯道相连道消去,那么可以考虑用广搜了,只要计算好路途中经过的弯道数就可以了。可以以弯道数不大于2为剪枝条件。入队前标记。不过在判断能否入队列前应该先把下一步要到达的点的弯道数和方向赋值好。就是先赋值再判断能否入队列,两者是互不相干的,但是不知道为什么调转了就会错。还有就是再使用BFS函数之前就可以把一些特殊情况的点判断出能否消去,比如而且两个点不可以存在是0类型的点,也不可以是始点跟终点为相同的一个点。细节问题还是看代码吧,我自己也是看了很多他人的代码才发现自己的只是因为赋值跟判断能否入队列调转了,我的是能入队列就赋值,不能就不管。这样错了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<queue> 3 #include<string> 4 using namespace std; 5 6 const int Max = 1005; 7 int n, m, k; 8 int to[4][2] = {0,1, 0,-1, 1,0, -1,0}; //→ ← ↓↑ 9 int map[Max][Max]; 10 bool used[Max][Max]; 11 12 typedef struct Node 13 { 14 bool operator==(const Node &n)const 15 { 16 return x==n.x && y==n.y && c==n.c; 17 } 18 int x, y, s, w; 19 int c; 20 }Node; 21 Node S, T, go, st; 22 23 int BFS() 24 { 25 queue<Node>Q; 26 27 used[S.x][S.y] = true; 28 Q.push(S); 29 30 while(!Q.empty()) 31 { 32 st = Q.front(); 33 Q.pop(); 34 if(st.x==T.x && st.y==T.y ) 35 return 1; 36 for(int i=0; i<4; i++) 37 { 38 go = st; 39 go.x += to[i][0]; 40 go.y += to[i][1]; 41 if(st.s!=i && st.s!=-1) //分向改变 弯数加一 42 { 43 go.w = st.w+1; 44 } 45 go.s = i; //另其方向变为当前方向 46 go.c = map[go.x][go.y]; 47 if(go.x>=1 && go.x<=n && go.y>=1 && go.y<=m && go.w<=2 && !used[go.x][go.y] //把转弯数控制在2次以内 48 && (map[go.x][go.y]==0 || (go.x==T.x && go.y==T.y))) 49 { 50 used[go.x][go.y] = true; //用过的点就不能再用了 51 Q.push(go); //符合条件就入队列 52 } 53 } 54 } 55 return 0; 56 } 57 int main() 58 { 59 int i, j; 60 while(cin>>n>>m && n||m) 61 { 62 memset(map, 0, sizeof(map)); 63 for(i=1; i<=n; i++) 64 { 65 for(j=1; j<=m; j++) 66 { 67 scanf("%d", &map[i][j]); 68 } 69 } 70 cin>>k; 71 for(i=0; i<k; i++) 72 { 73 scanf("%d%d%d%d", &S.x, &S.y, &T.x, &T.y); 74 S.s = -1; 75 S.w = 0; 76 S.c = map[S.x][S.y]; 77 T.c = map[T.x][T.y]; 78 if(S.c == 0 || T.c == 0 || S.c!=T.c || S==T) 79 { //如果其始点跟终点是同一个点或者其中有一个点为0,那么就不可能消去 80 cout<<"NO"<<endl; 81 continue; 82 } 83 memset(used, false, sizeof(used)); 84 if(BFS()) 85 cout<<"YES"<<endl; 86 else 87 cout<<"NO"<<endl; 88 } 89 } 90 return 0; 91 }