1066 - Gathering Food
Winter is approaching! The weather is getting colder and days are becoming shorter. The animals take different measures to adjust themselves during this season.
- Some of them "migrate." This means they travel to other places where the weather is warmer.
- Few animals remain and stay active in the winter.
- Some animals "hibernate" for all of the winter. This is a very deep sleep. The animal‘s body temperature drops, and its heartbeat and breathing slow down. In the fall, these animals get ready for winter by eating extra food and storing it as body fat.
For this problem, we are interested in the 3rd example and we will be focusing on ‘Yogi Bear‘.
Yogi Bear is in the middle of some forest. The forest can be modeled as a square grid of size N x N. Each cell of the grid consists of one of the following.
. an empty space
# an obstacle
[A-Z] an English alphabet
There will be at least 1 alphabet and all the letters in the grid will be distinct. If there are k letters, then it will be from the first k alphabets. Suppose k = 3, that means there will be exactly one A, one B and one C.
The letters actually represent foods lying on the ground. Yogi starts from position ‘A‘ and sets off with a basket in the hope of collecting all other foods. Yogi can move to a cell if it shares an edge with the current one. For some superstitious reason, Yogi decides to collect all the foods in order. That is, he first collects A, then B, then C and so on until he reaches the food with the highest alphabet value. Another philosophy he follows is that if he lands on a particular food he must collect it.
Help Yogi to collect all the foods in minimum number of moves so that he can have a long sleep in the winter.
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case contains a blank line and an integer N (0 < N < 11), the size of the grid. Each of the next N lines contains N characters each.
Output
For each case, output the case number first. If it‘s impossible to collect all the foods, output ‘Impossible‘. Otherwise, print the shortest distance.
Sample Input |
Output for Sample Input |
4 5 A.... ####. ..B.. .#### C.DE. 2 AC .B 2 A# #B 3 A.C ##. B.. |
Case 1: 15 Case 2: 3 Case 3: Impossible Case 4: Impossible |
题目大意:其实题意挺好理解的,就是去摘果,然后需要从A点开始,然后摘到字符出现的最后一个字母。地图是n*n 然后字母一定是从A 开始顺序递增,而且不会超过26个。有个小坑点,就是摘过这个字母的时候,这条路是可以走的,比如你过了B这个点,那么B这个点就相当于变成‘.‘。 知道这个,,每次到达一个字母,就设为起始点,bfs 之后初始化 ,再BFs 知道走到最后一个字母,这样就OK了。
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 char map[20][20]; //记录地图 7 int vis[20][20]; //访问标记 8 int dir[4][2] = {0,1,0,-1,1,0,-1,0}; //四个方向 9 int n; //行和列 10 int ans; //记录走过的字母个数 11 struct state 12 { 13 int x,y; //记录坐标 14 int count; //记录步数 15 char c; //字符 16 }sta[600]; 17 18 int res = 0; //记录最后的答案 19 int check(state s, char c) 20 { 21 if ( vis[s.x][s.y] == 0 && s.x >= 0 &&s.x < n && s.y >= 0 && s.y < n && (s.c ==‘.‘||(s.c <= c && s.c >= ‘A‘ && s.c <= ‘Z‘))) //判断可以不可以走 22 { 23 return 1; 24 } 25 else 26 { 27 return 0; 28 } 29 } 30 31 void bfs(state s,char c) //bfs算法 32 { 33 queue <state> q; //定义队列 34 state now,next; //现在的 和下一个 35 s.count = 0; //初始化步数 36 q.push(s); //入队 37 vis[s.x][s.y] = 1; 38 while (!q.empty()) 39 { 40 now = q.front(); //队首元素 41 q.pop(); //出队 42 if (now.c == c ) //如果走到目标字母 43 { 44 ans++; 45 res += now.count; //结果加上走的步数 46 map[now.x][now.y] = ‘.‘; //然后走过的字母变为‘.‘ 47 now.count = 0; 48 next.count = 0; 49 memset(vis,0,sizeof(vis)); //初始化走过的路 50 return ; 51 } 52 for ( int i = 0 ; i < 4 ;i++) 53 { 54 next.x = now.x + dir[i][0]; 55 next.y = now.y + dir[i][1]; 56 next.count = now.count + 1; //四个方向 57 next.c = map[next.x][next.y]; 58 if (check(next , c)) 59 { 60 q.push(next); //如果符合条件,入队 61 vis[next.x][next.y] = 1; //访问过了 不再访问 62 } 63 } 64 65 } 66 return; //如果无路可走 退出 67 } 68 69 int main() 70 { 71 int t; 72 scanf("%d",&t); 73 int temp[26]; 74 for (int cas = 1 ; cas <= t ; cas ++ ) 75 { 76 memset(vis,0,sizeof(vis)); 77 res = 0; 78 ans = 1; 79 scanf("%d",&n); 80 getchar(); 81 int k = 0; 82 int l = 0; 83 for (int i = 0 ; i < n ; i++ ) 84 { 85 for ( int j = 0 ; j < n ; j++ ) 86 { 87 scanf("%c",&sta[l].c); 88 map[i][j] = sta[l].c; //结构数组的字符 89 sta[l].x = i; 90 sta[l].y = j; 91 if (sta[l].c >= ‘A‘ && sta[l].c <= ‘Z‘) 92 { 93 temp[sta[l].c-‘A‘] = l; 94 k++; //字母总个数 95 } 96 l++; //结构数组的下标 97 } 98 getchar(); 99 } 100 for (int i = 1 ; i < k ; i++ ) 101 { 102 //printf("%c\n",sta[temp[i-1]].c); 103 bfs(sta[temp[i-1]],(‘A‘ + i)); //记录A 到B的路径 然后再B到C 的路径,直到最后一个 104 if ( ans < i ) 105 break; 106 } 107 if (ans == k && k > 0) //如果字母全部走过了 108 { 109 printf("Case %d: %d\n",cas, res); 110 } 111 else 112 { 113 printf("Case %d: Impossible\n",cas); //没有走遍所有的字母 114 } 115 if ( cas != t) 116 getchar(); 117 } 118 return 0; 119 }
light oj 1066Gathering Food (bfs 稍微有点小坑)