Going Together

C - Going Together
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu
Submit  Status

Description

You are playing a computer game in which three robots (Aneed, Ben and Cindy) are trapped in a labyrinth. Initially all three are situated in three different locations in the maze. There are three outlets through which the robots have to exit. As expected, there are several obstacles in the maze and the robots can't go through them.

The maze can be modeled as a square grid with N x N cells. The robots are placed on three different cells into the maze. You can command them to move. A single command will be activated for the three robots simultaneously. A robot will move to a new position (whatever its current situation is) if it is an empty cell within the maze or it is one of the free target cells, otherwise the command will be ignored for that robot. Your task is to command them such a way that all of them are on three exit cells (in any order).

A move consists of one of the following (Each move takes 1 unit of time):

Move North   The robots move one cell north.

Move East      The robots move one cell east.

Move South    The robots move one cell south.

Move West     The robots move one cell west.

Each cell consists of one of the following characters:

A - Initial position of Aneed

B - Initial position of Ben

C - Initial position of Cindy

. - An empty cell

# - An obstacle

X - A target cell

You can assume that for every maze each of the letters (A B C) will appear exactly once and the letter X will appear exactly three times.

Input

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case starts with an integer N (2 < N < 10). Each of the next N lines contains N characters that fill up the maze.

Output

For each case, output the case number followed by the minimum time required. If it is impossible to move them as described, print 'trapped' instead of the time.

Sample Input

3

7

.....#.

.......

.#B....

...A.#.

.CX....

.X.X.#.

.#.....

3

ABC

...

XXX

3

ABC

###

XXX

Sample Output

Case 1: 2

Case 2: 2

Case 3: trapped



PS:小学玩过这游戏,很难过关。。。。

就是说有个N*N的地图,A、B、C是三个机器人,X是目的地,#是墙壁

你每次可以发一条命令,命令机器人向上下左右四个方向的其中一个反向移动,且一条命令发出,三个机器人是一起移动的,

如果前进方向是墙壁或是另外一个机器人,则保持原位不动

题目要求出三个机器人一起移动目的地的最少步数,一个X只能放一个机器人

我直接用BFS

一个结构体存三个机器人的坐标跟走过的步数

还要一个标记数组,记录走过的位置,如果之前有走出这种位置,则不存进队列


最近写五子棋AI,学到了一种方法,把二维数组用一维数组保存,这样就只需要一个位置,不用坐标x跟y。不过数组会开得比二维数组大


下面是代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<queue>
using namespace std;

struct Robot
{
	int a;
	int b;
	int c;
	int count;
}robot;

queue<Robot> robots;
int dis[4] = { 1, -1 };
char map[150];
bool flag[150][150][150] = { false };

int n;

void bfs()
{
	while (!robots.empty())
	{
		Robot r = robots.front();
		robots.pop();
		for (int i = 0; i < 4;++i)
		{
			//方向步进量为dis[i];
			int pa = r.a + dis[i];
			int pb = r.b + dis[i];
			int pc = r.c + dis[i];
			int pco = r.count + 1;
			//如果前进之后的位置是墙,则不前进
			if (map[pa] == '#')
			{
				pa = r.a;
			}
			if (map[pb] == '#')
			{
				pb = r.b;
			}
			if (map[pc] == '#')
			{
				pc = r.c;
			}
			//如果有两个机器人重叠,则那个原来不是在这个位置的机器人回到原来的位置
			if (pa == r.a)
			{
				if (pb == pa)
				{
					pb = r.b;
				}
				if (pc == pa)
				{
					pc = r.c;
				}
			}
			if (pb == r.b)
			{
				if (pa == pb)
				{
					pa = r.a;
				}
				if (pc == pb)
				{
					pc = r.c;
				}
			}
			if (pc == r.c)
			{
				if (pa == pc)
				{
					pa = r.a;
				}
				if (pb == pc)
				{
					pb = r.b;
				}
			}
			if (pa != pb && pb != pc && pa != pc)
			{
				//如果三个都到了目的地,可以退出搜索了
				if (map[pa] == 'X' && map[pb] == 'X' && map[pc] == 'X')
				{
					cout << pco << endl;
					while (!robots.empty())
					{
						robots.pop();
					}
					return;
				}
				//否则如果该位置不是走过的,则存进队列
				if (!(pa == r.a && pb == r.b && pc == r.c) && !flag[pa][pb][pc])
				{
					robot.a = pa;
					robot.b = pb;
					robot.c = pc;
					robot.count = pco;
					flag[pa][pb][pc] = true;
					robots.push(robot);
				}
			}
		}
	}
	cout << "trapped" << endl;
}

int main()
{
	int t;
	cin >> t;
	for (int i = 1; i <= t; ++i)
	{
		cin >> n;
		//向下走一步的步进量
		dis[2] = n + 1;
		//向上走一步的步进量
		dis[3] = -(n + 1);
		memset(map, 0, sizeof(map));
		memset(flag, 0, sizeof(flag));
		robot.count = 0;
		//放置哨兵位
		for (int j = 0; j <= n; ++j)
		{
			map[j] = map[j + (2 + n)*n + 1] = '#';
		}
		for (int j = 1; j <= n; ++j)
		{
			map[j * (n + 1)] = '#';
		}
		//存地图
		for (int j = 0; j < n; ++j)
		{
			for (int k = 0; k < n; ++k)
			{
				int pos = n + 2 + k + j * (n + 1);
				cin >> map[pos];
				switch (map[pos])
				{
				case 'A':
					robot.a = pos;
					break;
				case 'B':
					robot.b = pos;
					break;
				case 'C':
					robot.c = pos;
					break;
				}
			}
		}
		//标记当前三个机器人的位置为走过的
		flag[robot.a][robot.b][robot.c] = true;
		//存进队列
		robots.push(robot);
		cout << "Case " << i << ": ";
		bfs();
	}

	return 0;
}



你可能感兴趣的:(Going Together)