3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间。
第二次WA,是因为没有枚举蛇的状态。
解体思路:
因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可。
然后多次BFS,先从起点到第一把钥匙,不能往回走,要用VIS数组标记。
第二次从第一把钥匙走到第二把钥匙。
最后一次从最后一把钥匙走到终点即可。
Tips 1: 在每次BFS过程中使用优先队列保证每次是最小步长的状态。
Tips2 :使用二进制枚举蛇的状态
Tips3:首先使用DFS判断是否绝对有解,如果无解输出"impossible",如果有解则继续。
Tips4:多次 BFS,而不是一次BFS,否则会导致状态太多TLE
代码如下:
1 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler 2 #include <stdio.h> 3 #include <iostream> 4 #include <cstring> 5 #include <cmath> 6 #include <stack> 7 #include <queue> 8 #include <vector> 9 #include <algorithm> 10 #define ll long long 11 #define Max(a,b) (((a) > (b)) ? (a) : (b)) 12 #define Min(a,b) (((a) < (b)) ? (a) : (b)) 13 #define Abs(x) (((x) > 0) ? (x) : (-(x))) 14 using namespace std; 15 16 const int INF = 0x3f3f3f3f; 17 const int MAXN = 220; 18 const double eps = 1e-9; 19 20 struct node{ 21 int x,y,step; 22 }; 23 24 char map[105][105]; 25 int vis[105][105]; 26 int to[4][2]= {1,0,-1,0,0,1,0,-1}; 27 int n,m,sx,sy,ex,ey,ans; 28 29 bool operator < (node a, node b){ 30 return a.step > b.step; 31 } 32 33 int check(int x,int y){ 34 if(x<0 || x>=n || y<0 || y>=n) 35 return 1; 36 if(map[x][y]=='#' || vis[x][y]) 37 return 1; 38 return 0; 39 } 40 41 void bfs(int sx, int sy, int k){ 42 int i; 43 priority_queue <node> Q; 44 node a,next; 45 a.x = sx; 46 a.y = sy; 47 a.step = 0; 48 vis[a.x][a.y]=1; 49 Q.push(a); 50 while(!Q.empty()){ 51 a = Q.top(); 52 //printf("x = %d y = %d step = %d\n",a.x,a.y,a.step); 53 Q.pop(); 54 if(k <= m){ 55 if(map[a.x][a.y] == k + '0'){ 56 ans += a.step; 57 ex = a.x; 58 ey = a.y; 59 //printf("%d %d cur _ ans = %d\n",ex, ey,ans); 60 return; 61 } 62 } else{ 63 if(map[a.x][a.y] == 'T'){ 64 ans += a.step; 65 ex = a.x; 66 ey = a.y; 67 //printf("%d %d cur _ ans = %d\n",ex, ey,ans); 68 return; 69 } 70 } 71 for(i = 0; i<4; i++){ 72 next = a; 73 next.x+=to[i][0]; 74 next.y+=to[i][1]; 75 if(check(next.x,next.y)) continue; 76 next.step=a.step+1; 77 if(map[a.x][a.y] == 'S'){ 78 ++next.step; 79 } 80 vis[next.x][next.y] = 1; 81 Q.push(next); 82 } 83 if(map[a.x][a.y] == 'S'){ 84 map[a.x][a.y] = '.'; 85 } 86 } 87 ans =INF; 88 return ; 89 } 90 91 void dfs(int x, int y){ 92 for(int i = 0; i<4; i++){ 93 int _x = x + to[i][0]; 94 int _y = y + to[i][1]; 95 if(check(_x,_y)) continue; 96 if(map[_x][_y] != '#'){ 97 vis[_x][_y] = 1; 98 dfs(_x,_y); 99 } 100 } 101 } 102 int main(){ 103 int i,j,cc,s_flag; 104 while(EOF != scanf("%d%d",&n,&m)){ 105 if(n == 0 && m == 0) break; 106 s_flag = 0; 107 node S[6]; 108 for(i = 0; i<n; i++) 109 scanf("%s",map[i]); 110 for(i = 0; i<n; i++){ 111 for(j = 0; j<n; j++){ 112 if(map[i][j]=='K'){ 113 sx = i; 114 sy = j; 115 }else if(map[i][j] == 'T'){ 116 ex = i,ey = j; 117 }else if(map[i][j] == 'S'){ 118 S[s_flag].x = i, S[s_flag++].y = j; 119 } 120 } 121 } 122 memset(vis,0,sizeof(vis)); 123 vis[sx][sy] = 1; 124 dfs(sx,sy); 125 int kkk[11]; 126 bool flag = false; 127 memset(kkk, 0, sizeof(kkk)); 128 for(i = 0; i < n; ++i){ 129 for(j = 0; j < n; ++j){ 130 if(map[i][j] >= '1' && map[i][j] <= '9' && vis[i][j]){ 131 kkk[map[i][j] - '0'] = 1; 132 } 133 } 134 } 135 for(i = 1; i <= m; ++i){ 136 if(!kkk[i]) break; 137 } 138 if(i == m + 1) flag = true; 139 140 if(vis[ex][ey] == 0 || !flag){ 141 printf("impossible\n"); 142 continue; 143 } 144 s_flag = 0; 145 for(i = 0; i<n; i++){ 146 for(j = 0; j<n; j++){ 147 if(map[i][j] == 'S'){ 148 S[s_flag].x = i, S[s_flag++].y = j; 149 } 150 } 151 } 152 int minans=INF; 153 for(cc = 0; cc < (1 << s_flag); ++cc){ 154 ans = 0; 155 for(i = 0; i <s_flag; ++i){ 156 if((1 << i) & cc){ 157 map[S[i].x][S[i].y] = '.'; 158 ans++; 159 } 160 else { 161 map[S[i].x][S[i].y] = '#'; 162 } 163 } 164 for(i = 0; i < n; ++i){ 165 for(j = 0; j < n; ++j){ 166 if(map[i][j] == 'K'){ 167 ex = i; 168 ey = j; 169 } 170 } 171 } 172 for(int k = 1; k <= m + 1; ++k){ 173 memset(vis, 0, sizeof(vis)); 174 sx = ex; 175 sy = ey; 176 bfs(sx, sy, k); 177 } 178 minans=min(minans,ans); 179 } 180 printf("%d\n",minans); 181 } 182 return 0; 183 }