Gathering Food
Time Limit: 2000 ms Case Time Limit: 2000 ms Memory Limit: 32768 KB
Submit: 36 Accepted: 12
Description
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 sizeN 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 arek letters, then it will be from the first k alphabets. Supposek = 3, that means there will be exactly one A, oneB 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 collectsA, 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 nextN 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
Sample Input | Output for Sample Input |
4 5 A.... ####. ..B.. .#### C.DE. 2 AC .B 2 A# #B 3 A.C ##. B.. |
|
|
|
|
|
广搜,找到一条遍历 A -> B -> C ->D …… X 的路径,从A->B,B->C,C->D,.........每相邻俩字母之间广搜一次。。。。。。
注意题目要求如果遍历到 X
点,X 点有食物的话就必须拿走,拿走之后就想到一个空点了……我就是应为这 wa 了 N次……
1)
模拟队列:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=15;
bool vis[maxn][maxn];
int dir[4][2]= {{0,-1},{0,1},{1,0},{-1,0}};
int sx[30],sy[30];
char map[maxn][maxn];
struct data
{
int x,y,step;
}node[maxn*maxn];
int e,n;
int bfs(int x,int y,int ex,int ey)
{
int l=0,r=0;
char ss=map[ex][ey];
node[r].x=x;node[r].y=y;
node[r++].step=0;
vis[x][y]=1;
while(l<r)
{
data next,a;
a.x=node[l].x;
a.y=node[l].y;
a.step=node[l++].step;
for(int i=0; i<4; i++)
{
next.x=a.x+dir[i][0];
next.y=a.y+dir[i][1];
next.step=a.step+1;
if(next.x>=1&&next.x<=n&&next.y>=1&&next.y<=n&&!vis[next.x][next.y]&&map[next.x][next.y]!='#')
{
if(map[next.x][next.y]<='Z'&&map[next.x][next.y]>='A')
{
if(map[next.x][next.y]!=ss)
continue;
if(map[next.x][next.y]==ss)
return next.step;
}
vis[next.x][next.y]=1;
node[r].x=next.x,node[r].y=next.y;
node[r++].step=next.step;
}
}
}
return -1;
}
int main()
{
int cas=1,t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
e=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>map[i][j];
if(map[i][j]>='A'&&map[i][j]<='Z')
{
sx[map[i][j]-'A']=i;sy[map[i][j]-'A']=j;
e=max(e,map[i][j]-'A');
}
}
int ans=0,f=0;
map[sx[0]][sy[0]]='.';
for(i=1;i<=e;i++)
{
memset(vis,0,sizeof(vis));
j=bfs(sx[i-1],sy[i-1],sx[i],sy[i]);
map[sx[i]][sy[i]]='.';
if(j==-1)
{
f=1;break;
}
ans+=j;
}
if(f==1)
printf("Case %d: Impossible\n",cas++);
else
printf("Case %d: %d\n",cas++,ans);
}
return 0;
}
2)
使用库函数里的队列写的:
#include <queue>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=15;
char map[maxn][maxn];
int n,vis[maxn][maxn];
int px[30],py[30];
struct Node
{
int x,y,step;
Node(int a,int b,int c)
{
x=a,y=b,step=c;
}
};
int dir[][2]={{0,1},{0,-1},{1,0},{-1,0}};
int bfs(int sx,int sy,int ex,int ey)
{
memset(vis,0,sizeof(vis));
queue<Node> q;
q.push(Node(sx,sy,0));
vis[sx][sy]=1;
while(!q.empty())
{
Node cur=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int nx=cur.x+dir[i][0];
int ny=cur.y+dir[i][1];
if(nx<1||nx>n) continue;
if(ny<1||ny>n) continue;
if(vis[nx][ny]) continue;
if(nx==ex&&ny==ey) return cur.step+1;
if(map[nx][ny]!='.') continue;
vis[nx][ny]=1;
q.push(Node(nx,ny,cur.step+1));
}
}
return -1;
}
int main()
{
int ca,cas=1;
cin>>ca;
while(ca--)
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>map[i][j];
int num=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(map[i][j]!='.'&&map[i][j]!='#')
{
px[map[i][j]-'A']=i,py[map[i][j]-'A']=j;
num=max(num,map[i][j]-'A');
}
int ans=0;
bool yes=1;
map[px[0]][py[0]]='.';
for(int i=1;i<=num;i++)
{
int dis=bfs(px[i-1],py[i-1],px[i],py[i]);
map[px[i]][py[i]]='.';
if(dis==-1) { yes=0;break; }
ans+=dis;
}
if(yes) cout<<"Case "<<cas++<<": "<<ans<<endl;
else cout<<"Case "<<cas++<<": Impossible"<<endl;
}
return 0;
}