题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1411
题目大意:连连看,给出每次连线的两个坐标,求能消去多少方块,拐弯最多2次
Sample Input
3 4 1 1 2 2 3 3 4 4 2 2 1 1 6 1 1 1 2 1 3 1 4 2 1 2 2 2 3 2 4 3 1 3 2 3 3 3 4
0 0
Sample Output
12
分析:连线可以从外围绕过去,用BFS求出两个坐标能够到达的最少拐弯次数。注意是最少拐弯次数,而不是最短距离
这道题目坑死我了,倒不是因为它的算法难,是一些小知识点
代码如下:
1 # include<iostream> 2 # include<cstdio> 3 # include<cstring> 4 # include<queue> 5 using namespace std; 6 7 int n,m; 8 int map[105][105]; 9 bool vis[105][105]; 10 int dx[]= {-1,0,0,1}; 11 int dy[]= {0,-1,1,0}; 12 struct node 13 { 14 int x,y,turn; 15 } st; 16 queue<node>q; 17 18 bool BFS(int x1,int y1,int x2,int y2) 19 { 20 if(map[x1][y1]==0 || map[x2][y2]==0 ||map[x1][y1]!=map[x2][y2] ||x1==x2&&y1==y2) 21 return false; 22 st.x = x1; 23 st.y = y1; 24 while(!q.empty()) q.pop(); //坑死,while写成了if,半天没看出来 25 memset(vis,0,sizeof(vis)); 26 st.turn = -1; 27 q.push(st); 28 while(!q.empty()) 29 { 30 st = q.front(); 31 q.pop(); 32 33 node tmp; 34 for(int i=0; i<4; i++) 35 { 36 for(int j=1;; j++) 37 { 38 tmp.x = st.x + j*dx[i]; 39 tmp.y = st.y + j*dy[i]; 40 tmp.turn = st.turn+1; 41 if(tmp.x<0 || tmp.y<0 ||tmp.x>n+1 ||tmp.y>m+1) break; 42 if(map[tmp.x][tmp.y]) 43 { 44 if(tmp.x==x2 && tmp.y==y2) return true; 45 break; 46 } 47 if(vis[tmp.x][tmp.y]) continue; 48 vis[tmp.x][tmp.y] = 1; 49 if(tmp.turn<2) //等于2的没必要加入队列了,他已经是叶子了 50 q.push(tmp); 51 } 52 } 53 } 54 return false; 55 } 56 57 int main() 58 { 59 //freopen("in.txt","r",stdin); 60 int t,x1,y1,x2,y2; 61 while(scanf("%d%d",&n,&m) &&n &&m) //因为给出n、m为0结束,如果写不等于EOF会超时,错了好几次才反应过来 62 { 63 memset(map,0,sizeof(map)); 64 for(int i=1; i<=n; i++) 65 for(int j=1; j<=m; j++) 66 scanf("%d",&map[i][j]); 67 scanf("%d",&t); 68 int ans=0; 69 while(t--) 70 { 71 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 72 if(BFS(x1,y1,x2,y2)) 73 { 74 ans += 2; 75 map[x1][y1] = 0; 76 map[x2][y2] = 0; 77 } 78 } 79 printf("%d\n",ans); 80 } 81 return 0; 82 }
还有另外一种思路,具体看代码:
1 #include "stdio.h" 2 int a[102][102]; 3 int x1,y1,x2,y2; 4 int m,n; 5 int process() 6 { 7 int b[102][102]; 8 int i,j; 9 int temp,pos; 10 for(i=0;i<=n+1;i++) 11 for(j=0;j<=m+1;j++) 12 b[i][j]=a[i][j]; 13 if(b[x1][y1]!=b[x2][y2] || b[x1][y1]==0) return 0; 14 temp=1; 15 while(x1+temp<=n+1) 16 { 17 if(b[x1+temp][y1]==0) 18 { 19 b[x1+temp][y1]=-1; 20 temp++; 21 } 22 else if(x1+temp==x2 && y1==y2) return 1; 23 else break; 24 } 25 temp=1; 26 while(x1-temp>=0) 27 { 28 if(b[x1-temp][y1]==0) 29 { 30 b[x1-temp][y1]=-1; 31 temp++; 32 } 33 else if(x1-temp==x2 && y1==y2) return 1; 34 else break; 35 } 36 temp=1; 37 while(y1+temp<=m+1) 38 { 39 if(b[x1][y1+temp]==0) 40 { 41 b[x1][y1+temp]=-1; 42 temp++; 43 } 44 else if(x1==x2 && y1+temp==y2) return 1; 45 else break; 46 } 47 temp=1; 48 while(y1-temp>=0) 49 { 50 if(b[x1][y1-temp]==0) 51 { 52 b[x1][y1-temp]=-1; 53 temp++; 54 } 55 else if(x1==x2 && y1-temp==y2) return 1; 56 else break; 57 } 58 temp=1; 59 while(x2+temp<=n+1) 60 { 61 if(b[x2+temp][y2]==-1) return 1; 62 else if(b[x2+temp][y2]==0) 63 { 64 b[x2+temp][y2]=-2; 65 temp++; 66 } 67 else break; 68 } 69 temp=1; 70 while(x2-temp>=0) 71 { 72 if(b[x2-temp][y2]==-1) return 1; 73 else if(b[x2-temp][y2]==0) 74 { 75 b[x2-temp][y2]=-2; 76 temp++; 77 } 78 else break; 79 } 80 temp=1; 81 while(y2+temp<=m+1) 82 { 83 if(b[x2][y2+temp]==-1) return 1; 84 else if(b[x2][y2+temp]==0) 85 { 86 b[x2][y2+temp]=-2; 87 temp++; 88 } 89 else break; 90 } 91 temp=1; 92 while(y2-temp>=0) 93 { 94 if(b[x2][y2-temp]==-1) return 1; 95 else if(b[x2][y2-temp]==0) 96 { 97 b[x2][y2-temp]=-2; 98 temp++; 99 } 100 else break; 101 } 102 if(y2<y1) 103 { 104 temp=1; 105 while(x2+temp<=n+1 && b[x2+temp][y2]==-2) 106 { 107 pos=1; 108 while(y2+pos<=m+1 && b[x2+temp][y2+pos]==0) 109 pos++; 110 if(y2+pos<=m+1 && b[x2+temp][y2+pos]==-1) return 1; 111 temp++; 112 } 113 temp=1; 114 while(x2-temp>=0 && b[x2-temp][y2]==-2) 115 { 116 pos=1; 117 while(y2+pos<=m+1 && b[x2-temp][y2+pos]==0) 118 pos++; 119 if(y2+pos<=m+1 && b[x2-temp][y2+pos]==-1) return 1; 120 temp++; 121 } 122 } 123 else if(y2>y1) 124 { 125 temp=1; 126 while(x2+temp<=n+1 && b[x2+temp][y2]==-2) 127 { 128 pos=1; 129 while(y2-pos>=0 && b[x2+temp][y2-pos]==0) 130 pos++; 131 if(y2-pos>=0 && b[x2+temp][y2-pos]==-1) return 1; 132 temp++; 133 } 134 temp=1; 135 while(x2-temp>=0 && b[x2-temp][y2]==-2) 136 { 137 pos=1; 138 while(y2-pos>=0 && b[x2-temp][y2-pos]==0) 139 pos++; 140 if(y2-pos>=0 && b[x2-temp][y2-pos]==-1) return 1; 141 temp++; 142 } 143 } 144 if(x2<x1) 145 { 146 temp=1; 147 while(y2+temp<=m+1 && b[x2][y2+temp]==-2) 148 { 149 pos=1; 150 while(x2+pos<=n+1 && b[x2+pos][y2+temp]==0) 151 pos++; 152 if(x2+pos<=n+1 && b[x2+pos][y2+temp]==-1) return 1; 153 temp++; 154 } 155 temp=1; 156 while(y2-temp>=0 && b[x2][y2-temp]==-2) 157 { 158 pos=1; 159 while(x2+pos<=n+1 && b[x2+pos][y2-temp]==0) 160 pos++; 161 if(x2+pos<=n+1 && b[x2+pos][y2-temp]==-1) return 1; 162 temp++; 163 } 164 } 165 else if(x2>x1) 166 { 167 temp=1; 168 while(y2+temp<=m+1 && b[x2][y2+temp]==-2) 169 { 170 pos=1; 171 while(x2-pos>=0 && b[x2-pos][y2+temp]==0) 172 pos++; 173 if(x2-pos>=0 && b[x2-pos][y2+temp]==-1) return 1; 174 temp++; 175 } 176 temp=1; 177 while(y2-temp>=0 && b[x2][y2-temp]==-2) 178 { 179 pos=1; 180 while(x2-pos>=0 && b[x2-pos][y2-temp]==0) 181 pos++; 182 if(x2-pos>=0 && b[x2-pos][y2-temp]==-1) return 1; 183 temp++; 184 } 185 } 186 return 0; 187 } 188 int main() 189 { 190 int step; 191 int i,j; 192 int num; 193 scanf("%d%d",&n,&m); 194 while(n!=0 || m!=0) 195 { 196 num=0; 197 for(i=0;i<=n+1;i++) 198 for(j=0;j<=m+1;j++) 199 a[i][j]=0; 200 for(i=1;i<=n;i++) 201 for(j=1;j<=m;j++) 202 scanf("%d",&a[i][j]); 203 scanf("%d",&step); 204 for(i=0;i<step;i++) 205 { 206 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 207 if(process()==1) 208 { 209 a[x1][y1]=0;a[x2][y2]=0; 210 num=num+2; 211 } 212 } 213 printf("%d\n",num); 214 scanf("%d%d",&n,&m); 215 } 216 return 0; 217 }