lightoj 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出发,收集完所有字母,且必须按字母的顺序收集,如果可以收集完,输出最小步数,如果不能输出Impossible。这题明显是一个简单的BFS。。。但是有个坑就是他可以走以前走过的路,你收集完字母A了,以后就可以再走这一格。就是每收集到一个字母,就从这个字母开始一个新的BFS。

没过的可以试一下下面这组数据

1
4
C.A.
###.
...B
....


#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

int n,cnt;
char a[15][15];
int b[15][15];
int dir[4][2] = {0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,s,cnt;
};

void bfs(int x,int y)
{
    memset(b,0,sizeof(b));
    a[x][y] = '.';
    b[x][y] = 1;
    queue<node> q;
    node t,next;
    t.x = x;
    t.y = y;
    t.s = 0;
    t.cnt = 1;
    q.push(t);
    while(!q.empty())
    {
        t = q.front();
        q.pop();
        if(t.cnt == cnt)
        {
            printf("%d\n",t.s);
            return;
        }
        for(int i=0;i<4;i++)
        {
            int tx = t.x + dir[i][0];
            int ty = t.y + dir[i][1];
            if(tx < 0 || ty < 0 || tx >= n || ty >= n)
                continue;
            if(a[tx][ty] == '#' ||  b[tx][ty])
                continue;
            if(a[tx][ty] >= 'A' && a[tx][ty] <= 'Z' && a[tx][ty] - 'A' > t.cnt)
                continue;
            next.x = tx;
            next.y = ty;
            next.s = t.s + 1;
            next.cnt = t.cnt;
            if(a[tx][ty] != '.')
            {
                next.cnt++;
                a[tx][ty] = '.';
                memset(b,0,sizeof(b));
                while(!q.empty())
                    q.pop();
                b[tx][ty] = 1;
                q.push(next);
                break;
            }
            b[tx][ty] = 1;
            q.push(next);
        }
    }
    printf("Impossible\n");
}
int main(void)
{
    int T,i,j,x,y;
    scanf("%d",&T);
    int cas = 1;
    while(T--)
    {
        scanf("%d",&n);
        cnt = 0;
        for(i=0;i<n;i++)
        {
            scanf("%s",a[i]);
            for(j=0;j<n;j++)
            {
                if(a[i][j] == 'A')
                    x = i, y = j;
                if(a[i][j] >= 'A' && a[i][j] <= 'Z')
                    cnt++;
            }
        }
        printf("Case %d: ",cas++);
        bfs(x,y);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值