【wikioi】1026 逃跑的拉尔夫
算法:BFS
14.01.02 PS: 本人再次脑残,BFS又是写得那么脓肿,突然发现我原来什么搜索都是不会的呀。。
//2014-02-05已更新
*******************************2013-10-15*******************************
题目描述:
年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置。
那个装置太旧了,以至于只能发射关于那辆车的移动路线的方向信息。
编写程序,通过使用一张小镇的地图帮助警察局找到那辆车。程序必须能表示出该车最终所有可能的位置。
小镇的地图是矩形的,上面的符号用来标明哪儿可以行车哪儿不行。“.”表示小镇上那块地方是可以行车的,而符号“X”表示此处不能行车。拉尔夫所开小车的初始位置用字符的“*”表示,且汽车能从初始位置通过。
汽车能向四个方向移动:向北(向上),向南(向下),向西(向左),向东(向右)。
拉尔夫所开小车的行动路线是通过一组给定的方向来描述的。在每个给定的方向,拉尔夫驾驶小车通过小镇上一个或更多的可行车地点。
此题要注意超空间和TLE,如果纯bfs的话肯定过不了2个点,所以加个三维数组判重(必须用3个,第3维表示用到方向的个数,要不然就错判了)
此题还要注意,这个BFS要沿着一个方向一直扩展下去,保持n不变(n是用到的方向数)
(这里不卡queue,我就不手打队列了)
其余的不多说,上代码:
#include <iostream>
#include <string>
#include <queue> using namespace std;
enum typemap{X, DOT, OK}; //自定义的地图,有3中状态,X表示‘X’,DOT表示‘.’,OK表示‘*’
enum fangxiang{N, S, W, E}; //自定义方向类型
//NORTH(北):N 、SOUTH(南):S 、WEST(西):W 、EAST(东):E
struct ma
{
int x, y, n; //n表示用到第几个
}f;
typemap map[52][52];
fangxiang fx[1050];
bool vis[52][52][1050]; //三维判重
int i, j, n, r, c;
char tem;
string temp;
queue<ma> q; int main()
{
cin >> r >> c;
for(i = 1; i <= r; i++) for(j = 1; j <= c; j++)
{
cin >> tem;
if(tem == '.') map[i][j] = DOT;
else if(tem == 'X') map[i][j] = X;
else {f.x = i; f.y = j; map[i][j] = OK;}
}
f.n = 1;
map[f.x][f.y] = DOT; //从这个方向搜的时候最后可能OK不存在(即不走回原点)故要把标志去掉
cin >> n;
for(i = 1; i <= n; i++)
{
cin >> temp;
if(temp=="NORTH") fx[i]=N;
else if(temp=="SOUTH") fx[i]=S;
else if(temp=="WEST") fx[i]=W;
else fx[i]=E;
}
q.push(f);
while(!q.empty())
{
f = q.front(); q.pop();
if(f.n > n) {map[f.x][f.y] = OK; continue;}
if(fx[f.n] == N)
{
f.n++;
while(f.x>1) //一直延展下去
{
if(map[f.x-1][f.y] == X || vis[f.x-1][f.y][f.n]) break;
f.x--;
q.push(f);
vis[f.x][f.y][f.n] = 1; //标志
}
}
else if(fx[f.n] == S)
{
f.n++;
while(f.x<r)
{
if(map[f.x+1][f.y] == X || vis[f.x+1][f.y][f.n]) break;
f.x++;
q.push(f);
vis[f.x][f.y][f.n] = 1;
}
}
else if(fx[f.n] == W)
{
f.n++;
while(f.y>1)
{
if(map[f.x][f.y-1] == X || vis[f.x][f.y-1][f.n]) break;
f.y--;
q.push(f);
vis[f.x][f.y][f.n] = 1;
}
}
else if(fx[f.n] == E)
{
f.n++;
while(f.y<c)
{
if(map[f.x][f.y+1] == X || vis[f.x][f.y+1][f.n]) break;
f.y++;
q.push(f);
vis[f.x][f.y][f.n] = 1;
}
}
}
for(i = 1; i <= r; i++)
{
for(j = 1; j <= c; j++)
switch (map[i][j])
{
case DOT:
cout << '.';
break;
case OK:
cout << '*';
break;
case X:
cout << 'X';
break;
}
cout << endl;
}
return 0;
}
*******************************2014-02-05*******************************
重写了一下,原理和上面差不多的,注意边界处理即可
#include <iostream>
#include <string>
using namespace std; const int maxq = 10000000,
maxn = 52; struct Map {
int x, y, c;
Map& operator= (Map& a) { x = a.x; y = a.y; c = a.c; return *this; }
}q[maxq]; int map[maxn][maxn], R, C, n;
bool vis[maxn][maxn][1003];
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
int fx[1003]; void bfs() {
int f = 0, l = 1;
Map t;
while(f != l) {
if(q[f].c > n) { map[q[f].x][q[f].y] = 2; f++; continue; }
t = q[f]; int w = fx[t.c];
t.c = q[f].c + 1;
t.x += dx[w]; t.y += dy[w];
while(t.x >= 1 && t.x <= R && t.y >= 1 && t.y <= C && map[t.x][t.y] != 1 && !vis[t.x][t.y][t.c]) {
vis[t.x][t.y][t.c] = 1;
q[l++] = t;
t.x += dx[w]; t.y += dy[w];
}
f++;
}
} int main() {
cin >> R >> C;
int i, j;
char t;
string str;
for(i = 1; i <= R; ++i) for(j = 1; j <= C; ++j) {
cin >> t;
if(t == 'X') map[i][j] = 1;
if(t == '*') q[0].x = i, q[0].y = j;
}
cin >> n;
for(i = 1; i <= n; ++i) {
cin >> str;
if(str[0] == 'N') fx[i] = 0;
else if(str[0] == 'S') fx[i] = 1;
else if(str[0] == 'W') fx[i] = 2;
else fx[i] = 3;
}
q[0].c = 1;
bfs();
for(i = 1; i <= R; ++i) {
for(j = 1; j <= C; ++j) if(map[i][j] == 0) cout << '.'; else if(map[i][j] == 1) cout << 'X'; else cout << '*';
cout << endl;
}
return 0;
}
【wikioi】1026 逃跑的拉尔夫的更多相关文章
- WIKIOI 1026 逃跑的拉尔夫 深度优先搜索
/* 1026 逃跑的拉尔夫 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆 ...
- code vs 1026 逃跑的拉尔夫
1026 逃跑的拉尔夫 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走 ...
- codevs 1026 逃跑的拉尔夫 x
1026 逃跑的拉尔夫 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他 ...
- Codevs 1026 逃跑的拉尔夫
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且 ...
- AC日记——逃跑的拉尔夫 codevs 1026 (搜索)
1026 逃跑的拉尔夫 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 年轻的拉尔夫开玩笑地从一 ...
- Codevs1026 逃跑的拉尔夫
题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的移动 ...
- 洛谷P1189 逃跑的拉尔夫(SEARCH)
洛谷1189 SEARCH 题目描述 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的 ...
- P1189 SEARCH(逃跑的拉尔夫)
P1189 SEARCH 题目描述 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的移 ...
- Codevs1026 SEARCH(逃跑的拉尔夫 )(BFS)
SEARCH 时间限制: 1 Sec 内存限制: 128 MB提交: 11 解决: 4[提交][状态][讨论版] 题目描述 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警 ...
随机推荐
- Java获取、删除文件和目录
package javatest; import java.io.File; import java.util.ArrayList; import java.util.regex.Pattern; c ...
- java并发库 Lock 公平锁和非公平锁
jdk1.5并发包中ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁或非公平锁,关于两者区别,java并发编程实践里面有解释 公平锁: Threads acquir ...
- Master-Worker模式
并行程序设计模式--Master-Worker模式 简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进 ...
- SharePoint Word 转换PDF服务介绍及示例
前言:在SharePoint使用过程中,经常会发现将文档进行格式转换的需求,之前,看到SharePoint 2013有将PPT转换PDF文档的服务,后来,才发现SharePoint 2010开始,就有 ...
- css排版
先介绍如何设定字体.颜色.大小.段落空白等比较简单的应用,后面再介绍下比如首字下沉.首行缩进.最后讲一些常用的web页面中文排版,比如中文字的截断.固定宽度词内折行(word-wrap和word-br ...
- Java for LeetCode 155 Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...
- Spring配置JNDI的解决方案
我的配置环境是:Spring + Tomcat + MySql 说明: 1. $TOMCAT_HOME代表Tomcat的安装目录. 第一步:在Tomcat的$TOMCAT_HOME/conf/cont ...
- Kafka学习笔记(二):Partition分发策略
kafka版本0.8.2.1 Java客户端版本0.9.0.0 为了更好的实现负载均衡和消息的顺序性,Kafka Producer可以通过分发策略发送给指定的Partition.Kafka保证在par ...
- jquery 展开折叠效果
仅供参考 图片 jquery.js 自己处理 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"& ...
- 三种方法实现js跨域访问
转自:http://narutolby.iteye.com/blog/1464436 javascript跨域访问是web开发者经常遇到的问题,什么是跨域,一个域上加载的脚本获取或操作另一个域上的文档 ...