学习:
转化成图
1 //#include<bits/stdc++.h> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 typedef long long ll; 7 int n,m,k; 8 char maps[20][20]; 9 int vis[200][200][200]; 10 int num[20][20]; 11 int que[10000000][4]; 12 int connect[200][200]; 13 int goal[4]; 14 int all; 15 int ans = -1; 16 void bfs(){ 17 int front = 0 , rear = 1; 18 while(front < rear){ 19 int a = que[front][1] , b = que[front][2] , c = que[front][3]; 20 vis[a][b][c] = true; 21 int step = que[front][0]; 22 23 //cout << a << " - " << goal[1] << endl; 24 //cout << b << " - " << goal[2] << endl; 25 //cout << c << " - " << goal[3] << endl; 26 27 if(a == goal[1] && b == goal[2] && c == goal[3]){ 28 ans = step; 29 return; 30 } 31 // a 是图上某个点 , coonect是邻接表。 32 for(int i = 0 ; i <= connect[a][0] ; i ++){ 33 int na = i ? connect[a][i] : a; 34 for(int j = 0 ; j <= connect[b][0] ; j ++){ 35 int nb = j ? connect[b][j] : b; 36 for(int k = 0 ; k <= connect[c][0] ; k ++){ 37 int nc = k ? connect[c][k] : c; 38 if((na && nb && na == nb) ||(na && nc && na == nc)||(nb && nc && nb == nc)) continue; 39 if((na && nb) && na == b && nb == a) continue; 40 if((nb && nc) && nb == c && nc == b) continue; 41 if((na && nc) && na == c && nc == a) continue; 42 if(!vis[na][nb][nc]){ 43 vis[na][nb][nc] = true; 44 que[rear][0] = step + 1; 45 que[rear][1] = na; 46 que[rear][2] = nb; 47 que[rear][3] = nc; 48 rear ++; 49 } 50 } 51 } 52 } 53 front ++; 54 } 55 } 56 int main(){ 57 /** 58 *先计算有几个点, 1......n 59 *再遍历每个点 pos(1~n), 与之相邻的 建立邻接表 60 * 再将起点 终点映射为 图中的下标。 61 * */ 62 while(scanf("%d%d%d",&m,&n,&k) != EOF && (n||m||k)){ 63 getchar(); 64 for(int i = 0 ; i < n ; i ++){ 65 gets(maps[i]); 66 } 67 all = 0; 68 memset(connect,0,sizeof(connect)); 69 memset(num,0,sizeof(num)); 70 memset(vis,0,sizeof(vis)); 71 for(int i = 0 ; i < n ; i ++){ 72 for(int j = 0 ; j < m ; j ++){ 73 // 图的下标从一开始 74 if(maps[i][j] != ‘#‘) num[i][j] = ++all; 75 } 76 } 77 for(int i = 0 ; i < n ; i ++){ 78 for(int j = 0 ; j < m ; j ++){ 79 int &pos = num[i][j]; 80 if(num[i][j]){ 81 // 转为邻接表, connect[pos][0] 表示有几个点和该点相连。 82 if(num[i-1][j]) connect[pos][++connect[pos][0]] = num[i-1][j]; 83 if(num[i+1][j]) connect[pos][++connect[pos][0]] = num[i+1][j]; 84 if(num[i][j-1]) connect[pos][++connect[pos][0]] = num[i][j-1]; 85 if(num[i][j+1]) connect[pos][++connect[pos][0]] = num[i][j+1]; 86 } 87 } 88 } 89 90 que[0][1] = que[0][2] = que[0][3] = goal[1] = goal[2] = goal[3] = 0; 91 que[0][0] = 0; 92 for(int i = 0 ; i < n ; i ++){ 93 for(int j = 0 ; j < m ; j ++){ 94 if(num[i][j]){ 95 if(maps[i][j] == ‘a‘) que[0][1] = num[i][j]; 96 else if(maps[i][j] == ‘b‘) que[0][2] = num[i][j]; 97 else if(maps[i][j] == ‘c‘) que[0][3] = num[i][j]; 98 else if(maps[i][j] == ‘A‘) goal[1] = num[i][j]; 99 else if(maps[i][j] == ‘B‘) goal[2] = num[i][j]; 100 else if(maps[i][j] == ‘C‘) goal[3] = num[i][j]; 101 } 102 } 103 } 104 bfs(); 105 printf("%d\n",ans); 106 } 107 return 0; 108 } 109 /** 110 4 3 1 111 #### 112 #aA# 113 #### 114 5 5 2 115 ##### 116 #A#B# 117 # # 118 #b#a# 119 ##### 120 16 4 3 121 ################ 122 ## ########## ## 123 # ABCcba # 124 ################ 125 16 16 3 126 ################ 127 ### ## # ## 128 ## # ## # c# 129 # ## ########b# 130 # ## # # # # 131 # # ## # # ## 132 ## a# # # # # 133 ### ## #### ## # 134 ## # # # # 135 # ##### # ## ## 136 #### #B# # # 137 ## C# # ### 138 # # # ####### # 139 # ###### A## # 140 # # ## 141 ################ 142 0 0 0 143 36 144 */
时间: 2024-10-16 11:31:28