uva-10047

时间:2021-12-04 16:47:20

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

  

相关文章