题目链接:点我
第一次不太清楚怎么判重,现在懂了,等下次再做
1 /* 2 *HDU 4531 3 *BFS 4 *注意判重 5 */ 6 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <algorithm> 11 #include <map> 12 #include <set> 13 #include <string> 14 #include <queue> 15 #include <iostream> 16 using namespace std; 17 18 char str[3][3][6]; 19 char g[3][3][6]; 20 21 map<int,int>mp; 22 queue<int>q; 23 bool move[6];//是否可以移动,0~5对应1~3行,1~3列 24 25 //并查集判断连通 26 int F[50]; 27 int find(int x) 28 { 29 if(F[x]==-1)return x; 30 return F[x]=find(F[x]); 31 } 32 void bing(int x,int y) 33 { 34 int t1=find(x); 35 int t2=find(y); 36 if(t1!=t2)F[t1]=t2; 37 } 38 //并查集判断是不是连通 39 bool judge(int state)//判断状态state是不是连通 40 { 41 char temp[10]; 42 int t[10]; 43 sprintf(temp,"%09d",state); 44 for(int i=0;i<9;i++)t[i]=temp[i]-‘0‘; 45 for(int i=0;i<3;i++) 46 for(int j=0;j<3;j++) 47 { 48 int p=t[3*i+j]; 49 int x=p/3; 50 int y=p%3; 51 strcpy(g[i][j],str[x][y]); 52 } 53 memset(F,-1,sizeof(F)); 54 for(int i=0;i<3;i++) 55 for(int j=0;j<3;j++) 56 { 57 if(g[i][j][0]==g[i][j][2])bing(12*i+4*j,12*i+4*j+2); 58 if(g[i][j][0]==g[i][j][3])bing(12*i+4*j,12*i+4*j+3); 59 if(g[i][j][1]==g[i][j][2])bing(12*i+4*j+1,12*i+4*j+2); 60 if(g[i][j][1]==g[i][j][3])bing(12*i+4*j+1,12*i+4*j+3); 61 } 62 for(int i=0;i<3;i++) 63 { 64 if(g[i][0][3]==g[i][1][2])bing(12*i+3,12*i+4+2); 65 if(g[i][1][3]==g[i][2][2])bing(12*i+4+3,12*i+8+2); 66 } 67 for(int j=0;j<3;j++) 68 { 69 if(g[0][j][1]==g[1][j][0])bing(4*j+1,12+4*j+0); 70 if(g[1][j][1]==g[2][j][0])bing(12+4*j+1,24+4*j+0); 71 } 72 int R=-1,G=-1,B=-1,O=-1; 73 for(int i=0;i<3;i++) 74 for(int j=0;j<3;j++) 75 for(int k=0;k<4;k++) 76 { 77 int t1=find(12*i+4*j+k); 78 if(g[i][j][k]==‘R‘) 79 { 80 if(R==-1)R=t1; 81 else if(t1!=R)return false; 82 } 83 else if(g[i][j][k]==‘G‘) 84 { 85 if(G==-1)G=t1; 86 else if(t1!=G)return false; 87 } 88 else if(g[i][j][k]==‘B‘) 89 { 90 if(B==-1)B=t1; 91 else if(t1!=B)return false; 92 } 93 else 94 { 95 if(O==-1)O=t1; 96 else if(t1!=O)return false; 97 } 98 } 99 return true; 100 } 101 int bfs() 102 { 103 mp.clear(); 104 while(!q.empty())q.pop(); 105 int tmp,now; 106 char ss1[10],ss2[10]; 107 tmp=12345678; //初始是012345678 108 mp[tmp]=0; 109 q.push(tmp); 110 while(!q.empty()) 111 { 112 tmp=q.front(); 113 q.pop(); 114 if(judge(tmp))return mp[tmp]; 115 sprintf(ss1,"%09d",tmp); 116 117 for(int i=0;i<3;i++) 118 for(int j=0;j<3;j++) 119 { 120 int t=ss1[3*i+j]-‘0‘; 121 strcpy(g[i][j],str[t/3][t%3]); 122 } 123 //第一行的左右移动 124 if(move[0]) 125 { 126 strcpy(ss2,ss1); 127 ss2[0]=ss1[1]; 128 ss2[1]=ss1[2]; 129 ss2[2]=ss1[0]; 130 now=0; 131 for(int i=0;i<9;i++) 132 { 133 now*=10; 134 now+=ss2[i]-‘0‘; 135 } 136 if(mp.find(now)==mp.end()) 137 { 138 mp[now]=mp[tmp]+1; 139 q.push(now); 140 } 141 142 ss2[0]=ss1[2]; 143 ss2[1]=ss1[0]; 144 ss2[2]=ss1[1]; 145 now=0; 146 for(int i=0;i<9;i++) 147 { 148 now*=10; 149 now+=ss2[i]-‘0‘; 150 } 151 if(mp.find(now)==mp.end()) 152 { 153 mp[now]=mp[tmp]+1; 154 q.push(now); 155 } 156 157 } 158 159 //第二行的左右移动 160 if(move[1]) 161 { 162 strcpy(ss2,ss1); 163 ss2[3]=ss1[4]; 164 ss2[4]=ss1[5]; 165 ss2[5]=ss1[3]; 166 now=0; 167 for(int i=0;i<9;i++) 168 { 169 now*=10; 170 now+=ss2[i]-‘0‘; 171 } 172 if(mp.find(now)==mp.end()) 173 { 174 mp[now]=mp[tmp]+1; 175 q.push(now); 176 } 177 ss2[3]=ss1[5]; 178 ss2[4]=ss1[3]; 179 ss2[5]=ss1[4]; 180 now=0; 181 for(int i=0;i<9;i++) 182 { 183 now*=10; 184 now+=ss2[i]-‘0‘; 185 } 186 if(mp.find(now)==mp.end()) 187 { 188 mp[now]=mp[tmp]+1; 189 q.push(now); 190 } 191 } 192 193 194 //第三行的左右移动 195 if(move[2]) 196 { 197 strcpy(ss2,ss1); 198 ss2[6]=ss1[7]; 199 ss2[7]=ss1[8]; 200 ss2[8]=ss1[6]; 201 now=0; 202 for(int i=0;i<9;i++) 203 { 204 now*=10; 205 now+=ss2[i]-‘0‘; 206 } 207 if(mp.find(now)==mp.end()) 208 { 209 mp[now]=mp[tmp]+1; 210 q.push(now); 211 } 212 213 ss2[6]=ss1[8]; 214 ss2[7]=ss1[6]; 215 ss2[8]=ss1[7]; 216 now=0; 217 for(int i=0;i<9;i++) 218 { 219 now*=10; 220 now+=ss2[i]-‘0‘; 221 } 222 if(mp.find(now)==mp.end()) 223 { 224 mp[now]=mp[tmp]+1; 225 q.push(now); 226 } 227 228 } 229 230 231 //第一列的左右移动 232 if(move[3]) 233 { 234 strcpy(ss2,ss1); 235 ss2[0]=ss1[3]; 236 ss2[3]=ss1[6]; 237 ss2[6]=ss1[0]; 238 now=0; 239 for(int i=0;i<9;i++) 240 { 241 now*=10; 242 now+=ss2[i]-‘0‘; 243 } 244 if(mp.find(now)==mp.end()) 245 { 246 mp[now]=mp[tmp]+1; 247 q.push(now); 248 } 249 250 ss2[0]=ss1[6]; 251 ss2[3]=ss1[0]; 252 ss2[6]=ss1[3]; 253 now=0; 254 for(int i=0;i<9;i++) 255 { 256 now*=10; 257 now+=ss2[i]-‘0‘; 258 } 259 if(mp.find(now)==mp.end()) 260 { 261 mp[now]=mp[tmp]+1; 262 q.push(now); 263 } 264 265 } 266 267 //第二列的左右移动 268 if(move[4]) 269 { 270 strcpy(ss2,ss1); 271 ss2[1]=ss1[4]; 272 ss2[4]=ss1[7]; 273 ss2[7]=ss1[1]; 274 now=0; 275 for(int i=0;i<9;i++) 276 { 277 now*=10; 278 now+=ss2[i]-‘0‘; 279 } 280 if(mp.find(now)==mp.end()) 281 { 282 mp[now]=mp[tmp]+1; 283 q.push(now); 284 } 285 286 ss2[1]=ss1[7]; 287 ss2[4]=ss1[1]; 288 ss2[7]=ss1[4]; 289 now=0; 290 for(int i=0;i<9;i++) 291 { 292 now*=10; 293 now+=ss2[i]-‘0‘; 294 } 295 if(mp.find(now)==mp.end()) 296 { 297 mp[now]=mp[tmp]+1; 298 q.push(now); 299 } 300 301 } 302 303 //第三列的左右移动 304 if(move[5]) 305 { 306 strcpy(ss2,ss1); 307 ss2[2]=ss1[5]; 308 ss2[5]=ss1[8]; 309 ss2[8]=ss1[2]; 310 now=0; 311 for(int i=0;i<9;i++) 312 { 313 now*=10; 314 now+=ss2[i]-‘0‘; 315 } 316 if(mp.find(now)==mp.end()) 317 { 318 mp[now]=mp[tmp]+1; 319 q.push(now); 320 } 321 322 ss2[2]=ss1[8]; 323 ss2[5]=ss1[2]; 324 ss2[8]=ss1[5]; 325 now=0; 326 for(int i=0;i<9;i++) 327 { 328 now*=10; 329 now+=ss2[i]-‘0‘; 330 } 331 if(mp.find(now)==mp.end()) 332 { 333 mp[now]=mp[tmp]+1; 334 q.push(now); 335 } 336 } 337 338 } 339 return -1; 340 } 341 342 int main() 343 { 344 int T; 345 scanf("%d",&T); 346 int iCase=0; 347 while(T--) 348 { 349 iCase++; 350 printf("Case #%d: ",iCase); 351 for(int i=0;i<6;i++)move[i]=true; 352 for(int i=0;i<3;i++) 353 for(int j=0;j<3;j++) 354 { 355 scanf("%s",&str[i][j]); 356 if(str[i][j][4]==‘1‘)//所在的列和行不能移动 357 { 358 move[i]=false; 359 move[3+j]=false; 360 } 361 } 362 printf("%d\n",bfs()); 363 } 364 return 0; 365 }
时间: 2024-10-13 09:52:35