uva-10047

我们考虑一个特殊情况,一个独轮车是一个圆环,独轮车靠这个圆环运动,
这个圆环上涂有五个不同的颜色,如下图
每个颜色段的圆心角是72度,这个圆环在MxN个方格的棋盘上运动,
独轮车从棋盘中一个格子的中心点开始运动到下一个格子,
这次运动将会导致轮子围绕它的圆心旋转72度,比如上图中的第二个轮子,
当轮子在第一个格子中心的时候,轮子上颜色是蓝色段的边缘的中心点和地面相接触,
当轮子向前运动到下一个方格2的中心点时,和地面相接触的是白色颜色段的中心点.
棋盘内的一些方格是不允许圆环滚动进去,
圆环从棋盘上的某个方格开始移动到目标方格,并且耗费的时间是最小的.
圆环可以从任意一个方格移动到下一个方格,或者在当前的方格上向左或者向右转90度,
这俩个动作都将耗费1秒中.
刚开始时,圆环总是面向北,绿色的颜色段和地面接触,在目标方格上,绿色的颜色段必须和
地面接触,但是圆环朝向可以任意.
在圆环开始运动前,请帮助它找出是否可以运动到目的地,
如果可以,请算出最小的时间消耗.

超时代码--dfs

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

const int MAXR = 26;
int r, c;
int er, ec;
int maxTime = 0x7FFFFFFF;
/**
 * 每一个点都有一个状态,当前和地面接触的颜色,当前的耗时,
 * 有可能耗时久,但是颜色和地面接触是正确的,可以到终点
 */
struct Color
{
	int used;
	int time;
	int conn;
	Color()
	{
		conn = -1;
		used = 0;
		time = 0x7FFFFFFF;
	}
};
struct Node
{
	//是否可走
	int connection;
	//到达这个点曾经的颜色
	Color* a;
	Node()
	{
		connection = 0;
		a = new Color[5];
		for(int i = 0; i < 5; i++)
		{
			Color c;
			a[i] = c;
		}
	}
};
int caculateTime(int cDir, int nDir, int time)
{
	if(cDir == 3 && nDir == 0)
	{
		return time + 1;
	}
	else if(cDir == 0 && nDir == 3)
	{
		return time + 1;
	}
	int dx = nDir - cDir;
	dx = dx < 0 ? dx * -1 : dx;
	return time + dx;
}
void dfs(Node map[][MAXR], int sr, int sc, int color, int time, int dir,
		int* ok)
{
	if(sr < 0 || sr == r || sc < 0 || sc == c || map[sr][sc].connection == 0)
		return;
	if(map[sr][sc].a[color].conn == 0
			|| (map[sr][sc].a[color].used && map[sr][sc].a[color].time < time))
	{
		if(map[sr][sc].a[color].used && map[sr][sc].a[color].time < time)
			*ok = 2;
		return;
	}
	map[sr][sc].a[color].used = 1;
	map[sr][sc].a[color].time = time;
	if(sr == er && sc == ec && color == 0)
	{
		*ok = 1;
		maxTime = time < maxTime ? time : maxTime;
		return;
	}
	int ok2 = 0;
	int nColor = (color + 1) % 5;
	//上
	int nt = caculateTime(dir, 0, time);
	dfs(map, sr - 1, sc, nColor, nt + 1, 0, &ok2);
	//下
	nt = caculateTime(dir, 2, time);
	dfs(map, sr + 1, sc, nColor, nt + 1, 2, &ok2);
	//左
	nt = caculateTime(dir, 3, time);

	dfs(map, sr, sc - 1, nColor, nt + 1, 3, &ok2);
	//右
//	if(color == 0 && sc == 6)
//	{
//		cout << endl;
//	}
	nt = caculateTime(dir, 1, time);
	dfs(map, sr, sc + 1, nColor, nt + 1, 1, &ok2);
	if(ok2 == 1)
	{
		*ok = 1;
		map[sr][sc].a[color].conn = 1;
	}
	else if(ok2 == 0)
	{
//		if(color == 0 && sc == 6)
//		{
//			cout << endl;
//		}
		if(map[sr][sc].a[color].conn == -1)
			map[sr][sc].a[color].conn = 0;
	}
	else if(ok2 == 2)
	{
		*ok = 2;
	}

}

void print(Node map[MAXR][MAXR])
{
	int color = 0;
	for(int i = 1; i < 8; i++)
	{
		cout << "位置=" << i;
		int time = map[0][i].a[color].time;
		cout << "颜色=" << color;
		cout << "时间=" << time;
		cout << "是否联通=" << map[0][i].a[color].conn;
		color = (color + 1) % 5;
		cout << endl;
	}

}
int main()
{
	freopen("d:\1.txt", "r", stdin);
	string no = "destination not reachable";
	int t = 0;
	while (cin >> r >> c)
	{
		t++;
		maxTime = 0x7FFFFFFF;
		if(r == c && r == 0)
			return 0;
		char cc;
		if(t != 1)
		{
			cout << endl;
		}
		cout << "Case #" << t << endl;
		Node map[MAXR][MAXR];
		int sr, sc;
		er = MAXR;
		ec = MAXR;
		for(int i = 0; i < r; i++)
		{
			for(int j = 0; j < c; j++)
			{
				cin >> cc;
				Node node;
				if(cc != '#')
				{
					node.connection = 1;
					if(cc == 'S')
					{
						sr = i;
						sc = j;
					}
					else if(cc == 'T')
					{
						er = i;
						ec = j;
					}
				}
				map[i][j] = node;
			}
		}
		int ok = 0;
		dfs(map, sr, sc, 0, 0, 0, &ok);
		if(maxTime != 0X7FFFFFFF)
			cout << "minimum time = " << maxTime << " sec" << endl;
		else
			cout << no << endl;
		//print(map);
	}
	return 0;
}

  //测试用例

1 10
.S.....T..
1 3
S#T
10 10
#S.......#
#..#.##.##
#.##.##.##
.#....##.#
##.##..#.#
#..#.##...
#......##.
..##.##...
#.###...#.
#.....###T
5 10
.S........
..##.....#
..#...T...
..#.......
..#.......
15 15
S......#.......
.......#.......
......#.#....T.
......#..#.....
.....#...#.....
....#.....#...#
....#.#.#.#....
....#..#...#...
...#..##.#.#...
...#...#....#..
..#..#.#....#..
..#.#..#.....#.
.##..#.#.....#.
...#...#.....#.
#......#.......
1 10
.S.....T..
1 3
S#T
10 10
#S.......#
#..#.##.##
#.##.##.##
.#....##.#
##.##..#.#
#..#.##...
#......##.
..##.##...
#.###...#.
#.....###T
5 5
#S#..
#.#..
#.###
#...T
#####
10 10
S.........
..........
..........
..........
..........
..........
..........
..........
..........
........T.
3 3
ST#
##.
.#.
6 6
#.#...
#.S.#.
#####.
#..#..
#T##..
......
0 0

-----------------------------------

Case #1
minimum time = 13 sec

Case #2
destination not reachable

Case #3
minimum time = 49 sec

Case #4
minimum time = 19 sec

Case #5
minimum time = 82 sec

Case #6
minimum time = 13 sec

Case #7
destination not reachable

Case #8
minimum time = 49 sec

Case #9
minimum time = 17 sec

Case #10
minimum time = 30 sec

Case #11
minimum time = 14 sec

Case #12
minimum time = 30 sec

AC代码,BFS

Ac时间:0ms

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

const int MAXR = 26;
int r, c;
int er, ec;
int maxTime = 0x7FFFFFFF;

/**
 * 每一个点的状态有当前颜色,当前朝向
 */
struct Node
{
	int r;
	int c;
	int conn;
	int dir;
	int color;
	int time;
	friend bool operator <(const Node n1, const Node n2)
	{
		return n1.time > n2.time;
	}
	;

} dir[4] = { { -1, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 0 }, { 1, 0, 0, 0, 0, 0 },
		{ 0, -1, 0, 0, 0, 0 } };
int caculateTime(int cDir, int nDir, int time)
{
	if(cDir == 3 && nDir == 0)
	{
		return time + 1;
	}
	else if(cDir == 0 && nDir == 3)
	{
		return time + 1;
	}
	int dx = nDir - cDir;
	dx = dx < 0 ? dx * -1 : dx;
	return time + dx;
}
void bfs(int sr, int sc, int* ok, Node map[][MAXR])
{
	/**
	 * 每一个点的状态有当前颜色,当前朝向
	 */
	int vis[MAXR][MAXR][5][4];
	memset(vis, 0, sizeof(vis));
	priority_queue<Node> queue;
	Node node;
	node.r = sr;
	node.c = sc;
	node.dir = 0;
	node.time = 0;
	node.color = 0;
	vis[node.r][node.c][node.color][node.dir] = 1;
	queue.push(node);
	while (!queue.empty())
	{
		node = queue.top();
		queue.pop();
		//枚举位置
		if(node.r == er && node.c == ec && node.color == 0)
		{
			*ok = 1;
			maxTime = node.time;
			return;
		}
		int nr, nc;
		for(int i = 0; i < 4; i++)
		{
			Node node2;
			nr = dir[i].r + node.r;
			nc = dir[i].c + node.c;
			if(nr == -1 || nr == r || nc == -1 || nc == c
					|| map[nr][nc].conn == 0)
			{
				//超过边界,已经走过的状态
				continue;
			}
			node2.dir = i;
			int time = caculateTime(node.dir, i, node.time);
			if(i == node.dir)
			{
				node2.r = nr;
				node2.c = nc;
				node2.color = (node.color + 1) % 5;
				node2.time = time + 1;
			}
			else
			{
				node2.r = node.r;
				node2.c = node.c;
				node2.time = time;
				node2.color = node.color;
			}
			if(vis[node2.r][node2.c][node2.color][node2.dir] == 1)
				continue;
			vis[node2.r][node2.c][node2.color][node2.dir] = 1;
			queue.push(node2);
		}
	}
}

int main()
{
	freopen("d:\1.txt", "r", stdin);
	string no = "destination not reachable";
	int t = 0;
	while (cin >> r >> c)
	{
		t++;
		if(r == c && r == 0)
			return 0;
		char cc;
		Node map[MAXR][MAXR];
		int sr, sc;
		er = MAXR;
		ec = MAXR;
		for(int i = 0; i < r; i++)
		{
			for(int j = 0; j < c; j++)
			{
				cin >> cc;
				Node node;
				node.conn = 0;
				node.r = i;
				node.c = j;
				if(cc != '#')
				{
					node.conn = 1;
					if(cc == 'S')
					{
						sr = i;
						sc = j;
					}
					else if(cc == 'T')
					{
						er = i;
						ec = j;
					}
				}
				map[i][j] = node;
			}
		}
		int ok = 0;
		bfs(sr, sc, &ok, map);
		if(t != 1)
		{
			cout << endl;
		}
		cout << "Case #" << t << endl;
		if(ok)
			cout << "minimum time = " << maxTime << " sec" << endl;
		else
			cout << no << endl;
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/6953020.html