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

  

uva-10047的更多相关文章

  1. UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

    很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M): UVA 11624 写的比较挫 #include <iostream> #include ...

  2. UVa 10047,独轮车

    题目链接:https://uva.onlinejudge.org/external/100/10047.pdf 题目链接:http://vjudge.net/contest/132239#proble ...

  3. UVA 10047 The Monocycle

    大白图论第二题··· 题意:独轮车的轮子被均分成五块,每块一个颜色,每走过一个格子恰好转过一个颜色. 在一个迷宫中,只能向前走或者左转90度或右转90度(我曾天真的认为是向左走和向右走···),每个操 ...

  4. UVA 10047 - The Monocycle BFS

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  5. uva 10047 The Monocycle(搜索)

    好复杂的样子..其实就是纸老虎,多了方向.颜色两个状态罢了,依旧是bfs. 更新的时候注意处理好就行了,vis[][][][]要勇敢地开. 不过这个代码交了十几遍的submission error,手 ...

  6. uva 10047 the monocyle (四维bfs)

    算法指南白书 维护一个四维数组,走一步更新一步 #include<cstdio> #include<cstring> #include<queue> #includ ...

  7. UVA 10047 The Monocycle (状态记录广搜)

    Problem A: The Monocycle  A monocycle is a cycle that runs on one wheel and the one we will be consi ...

  8. UVa 10047 自行车 状态记录广搜

    每个格子(x,y,drection,color) #include<iostream> #include<cstdio> #include<cstring> #in ...

  9. 1.1.1最短路(Floyd、Dijstra、BellmanFord)

    转载自hr_whisper大佬的博客 [ 一.Dijkstra 比较详细的迪杰斯特拉算法讲解传送门 Dijkstra单源最短路算法,即计算从起点出发到每个点的最短路.所以Dijkstra常常作为其他算 ...

  10. 最短路算法详解(Dijkstra/SPFA/Floyd)

    新的整理版本版的地址见我新博客 http://www.hrwhisper.me/?p=1952 一.Dijkstra Dijkstra单源最短路算法,即计算从起点出发到每个点的最短路.所以Dijkst ...

随机推荐

  1. Quartz(一):Cron表达式

    正文 1. 表达式介绍 Cron:cron表达式用于配置cronTrigger的实例.cron表达式实际上是由七个子表达式组成.这些表达式之间用空格分隔. Cron格式:[秒] [分] [小时] [日 ...

  2. Oracle RAC 归档 与 非归档 切换

    Oracle 的生产库都是启动在归档模式下,RAC下归档非归档的切换和单实例也是一样的,都是在MOUNT模式下执行ALTER DATABASE ARCHIVELOG/NOARCHIVELOG;命令.  ...

  3. npm 使用

    npm 命令: 命令 作用 npm init 产生package.json文件 npm list <package> 查看安装的module版本 npm update <packag ...

  4. vue-cli 项目构建性能分析工具

    修改package.json { ... "scripts": { ... //新增 "analyz": "NODE_ENV=production n ...

  5. centos 修改host

    centos 修改host vi /etc/hosts添加一行127.0.0.1 test.com /etc/rc.d/init.d/network restart

  6. Jenkins进阶-发布后自动创建git tag(5)

    为了便于项目中对发布的版本进行回滚,所以我们每次发布完成以后自动创建git tag. 1,创建一个Jenkins任务,命名成为push_tag_demo: 2,配置<源码管理>,这里配置比 ...

  7. Sql中判断"数据库"、"表"、"临时表"、"存储过程"和列"是否存在

    --判断数据库是否存在 IF EXISTS (SELECT * FROM MASTER..sysdatabases WHERE NAME = '库名')    PRINT 'exists ' else ...

  8. Linux strace命令 一

    简介 strace常用来跟踪进程执行时的系统调用和所接收的信号. 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核 ...

  9. wxWidgets:消息处理流程

    首先解释下EventHandler. wxWidgets中EventHandler并不是简单的指消息(事件)处理函数,而是一个用于处理窗口系统消息的类.收到消息后,wxEventHandler会调用e ...

  10. Hadoop专业解决方案-第12章 为Hadoop应用构建企业级的安全解决方案

    一.前言: 非常感谢Hadoop专业解决方案群:313702010,兄弟们的大力支持,在此说一声辛苦了,春节期间,项目进度有所延迟,不过元宵节以后大家已经步入正轨, 目前第12章 为Hadoop应用构 ...