这道题目真是非常坎坷啊,WA了很多次,但所有的思路都是奔着广搜去想的,一开始出现了比答案大的数据,才想到了应该是优先队列,再说加上也肯定不会错。一开始我读错了题意,以为旋转并且前行需要的时间跟其他一样,但是旋转的动作是需要额外计时的。我的第一种方法错误原因还没有找到,我在旋转以后就直接改动了位置,感觉没有什么本质区别,旋转了以后,肯定要走啊,我直接加上时间也没什么问题,我也把所能想到的测试用例都试过了,与AC代码完全一致,真是搞不懂,这要是CF就好了。于是,学习了别人的代码,改了改我原先的地方,发现还真是那里错了。。又经过了一番钻研,才算优雅的AC了题目。

  吐槽就到这里了,我来说一下代码吧。

  状态使用四维数组保存,位置占两维,方向和颜色各占一维,颜色就是题目中给的5种颜色,方向最好给定一个标号,便于以后的行走。(0N ,1E, 2S,3W) ,在搜索过程中,每一次操作都将会耗费1秒种,操作分为向左右旋转,即改变dir,向目前的方向移动,改变x和y。 每次都让这3中新的状态进入优先队列,选择耗费时间小的作为队头,这样当搜索到的时候,便是耗费最小的步数。

#include<iostream>
#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
using namespace std;
#define maxn 30
struct Node{
int x,y,col,dir,tim;
bool operator < (Node a)const{
return a.tim < tim;
}
};
char maps[maxn][maxn];
int state[maxn][maxn][][],n,m,go[][]={{-,},{,},{,},{,-}};///注意按照自己规定的方向处理数组,便于行走
priority_queue<Node> que;
bool ok(Node a){
if(a.x>=&&a.x<n && a.y>=&&a.y<m && state[a.x][a.y][a.col][a.dir]== && maps[a.x][a.y]!='#') return true;
return false;
}
void mark(Node a){
state[a.x][a.y][a.col][a.dir] = ;
}
int BFS(Node s){
while(!que.empty()) que.pop();
que.push(s);
state[s.x][s.y][s.col][s.dir] = ;
while(!que.empty()){
Node now = que.top();
que.pop();
if(maps[now.x][now.y]== 'T' && now.col==) return now.tim;
Node nxt = now;
nxt.tim++;///每一次操作,耗费1s
nxt.dir = (now.dir + )%;
if(ok(nxt)){que.push(nxt); mark(nxt);}
///第一种向右转,注意是转 nxt.dir = now.dir - ; if(nxt.dir<) nxt.dir=;
if(ok(nxt)){que.push(nxt); mark(nxt);}
///第二种向左转 nxt.dir = now.dir;
nxt.col=(now.col+)%;
nxt.x = go[now.dir][] + now.x;
nxt.y = go[now.dir][] + now.y;
///向所在方向行走,并且改变颜色
if(ok(nxt)) {que.push(nxt); mark(nxt);}
}
return -;
}
int main()
{
int ca = ;
while(EOF != scanf("%d%d",&n,&m)){
if(n==&& m==) break;
if(ca) printf("\n"); ///注意不要多输出空行
for(int i = ;i < n;i++)
scanf("%s",maps[i]);
Node start;
memset(state,,sizeof(state));
for(int i = ;i < n;i++){
for(int j = ;j < m;j++){
if(maps[i][j]=='S'){
start.x = i; start.y = j;
start.col=; start.dir=;
start.tim = ;
}
}
}
int ans = BFS(start);
printf("Case #%d\n",++ca);
if(ans == -) printf("destination not reachable\n");
else printf("minimum time = %d sec\n",ans);
}
return ;
}

UVALive 2035 The Monocycle(BFS状态处理+优先队列)的更多相关文章

  1. hdoj 5094 Maze 【BFS + 状态压缩】 【好多坑】

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Sub ...

  2. ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

    求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其 ...

  3. hdu 1242:Rescue(BFS广搜 + 优先队列)

    Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  4. HDU1429+bfs+状态压缩

    bfs+状态压缩思路:用2进制表示每个钥匙是否已经被找到.. /* bfs+状态压缩 思路:用2进制表示每个钥匙是否已经被找到. */ #include<algorithm> #inclu ...

  5. BFS+状态压缩 hdu-1885-Key Task

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1885 题目意思: 给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应 ...

  6. poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)

    Description Flip game squares. One side of each piece is white and the other one is black and each p ...

  7. BFS+状态压缩 HDU1429

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...

  9. UVALive 3956 Key Task (bfs+状态压缩)

    Key Task 题目链接: http://acm.hust.edu.cn/vjudge/contest/129733#problem/D Description The Czech Technica ...

随机推荐

  1. FZU 1896 神奇的魔法数 dp

    网上都说是数位dp 但是虽然在队伍里负责动态规划 但是数位dp还不会…… 百度了一下 发现和最大子序列思路差不多…… 最大子序列的dp[i][j]是表示两个序列前i项和前j项的最大子序列…… dp[i ...

  2. Gentoo解决Windows双系统时间不同步的问题

    升级后的gentoo不再使用/etc/conf.d/clock,而是使用/etc/conf.d/hwclock来设置和时间相关了. 在/etc/conf.d/hwclock文件中设置系统时间为本地时间 ...

  3. OAuth流程

    简介 OAuth是一种协议,OAuth协议为用户资源的授权提供了一个安全的.开放而又简易的标准 第三方若想访问用户资源,就必须遵守服务提供商实现的OAuth协议 OAuth授权的步骤(新浪微博为例) ...

  4. How can I create an Asynchronous function in Javascript?

    哈哈:)我的codepen 的代码笔记是:http://codepen.io/shinewaker/pen/eBwPxJ --------------------------------------- ...

  5. JPA 系列教程12-复合主键-2个@Id+@IdClass

    复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id一样 Airline p ...

  6. SOUI入门

    环境:win7_64旗舰版,VS2013 发现了一个比较好用的DirectUI库——SOUI,但是写一个窗口程序不是很方便,程序初始化的地方稍显繁琐,这里稍微封装一下. 大概包含6个文件: SouiC ...

  7. js导入的注意.txt

    如有两个外部js文件: jquery-1.8.2.min.js Jqery的系统文件 LYFArray.js 和个人的 ===============我要将两个js文件导入一个页面的方法:====== ...

  8. HDU 5755 Gambler Bo

    可以设n*m个未知量,建立n*m个方程.位置i,j可以建立方程 (2*x[i*m+j]+x[(i-1)*m+j]+x[(i+1)*m+j]+x[i*m+j-1]+x[i*m+j+1])%3=3-b[i ...

  9. 如何在VS2013中显示代码行号

    http://jingyan.baidu.com/article/af9f5a2d2e193543140a4533.html

  10. leetcode24,交换链表相邻的节点

    Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2-& ...