我们考虑一个特殊情况,一个独轮车是一个圆环,独轮车靠这个圆环运动,
这个圆环上涂有五个不同的颜色,如下图
每个颜色段的圆心角是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; }