[2016-02-24][UVA][1601][The Morning after Halloween]

  • 时间:2016-02-24 15:49:41 星期三
  • 题目编号:UVA 1601
  • 题目大意:给定一个迷宫图,至多3个小写字母和等数目大写字符,求小写字母移动到大写字母的最少步数
  • 迷宫宽度范围是4~16,字母个数是1~3,
  • 分析:求最少步数,BFS,知道终点状态,可以用双向bfs优化
  • 方法:BFS

//单向bfs

#include<iostream>

#include<cstdio>

#include<queue>

#include<cstring>

#include<algorithm>

using namespace std;

struct Node{

int t,now[3];

Node(int _t,int a = -1,int b = -1,int c = -1):t(_t){

now[0] = a;now[1] = b;now[2]= c;

}

};

struct Edge{

int to,nxt;

};

Edge e[2000];

char mp[17][17];

int w,h,n,cnt,head[267];

int goal[3],start[3],vis[268][268][268];

int d[5][2] = {{0,0},{-1,0},{1,0},{0,1},{0,-1}};

void add(int u,int v){

e[cnt].to = v;

e[cnt].nxt = head[u];

head[u] = cnt++;

}

void init(){

cnt = 0;

memset(start,-1,sizeof(start));

memset(goal,-1,sizeof(goal));

memset(head,-1,sizeof(head));

for(int i = 0; i < h ;++i){

for(int j = 0;j < w;++j){

if(mp[i][j] == ‘#‘)     continue;

if(mp[i][j] >= ‘a‘ && mp[i][j] <= ‘c‘)

start[ mp[i][j] - ‘a‘ ] = i*w + j;

if(mp[i][j] >= ‘A‘ && mp[i][j] <= ‘C‘)

goal[ mp[i][j] - ‘A‘ ] = i*w + j;

for(int k = 0;k < 5;++k){

int ni = i + d[k][0],nj = j + d[k][1];

if(ni >= 0 && ni < h && nj >=0 && nj<w && mp[ni][nj]!=‘#‘)

add(i*w+j,ni*w+nj);

}

}

}

}

int bfs(){

queue<Node> q;

memset(vis,0,sizeof(vis));

vis[start[0]+10][start[1]+10][start[2]+10] = 1;

q.push(Node(0,start[0],start[1],start[2]));

while(!q.empty()){

Node u = q.front();q.pop();

if(memcmp(u.now,goal,sizeof(goal)) == 0)

return u.t;

if(n==1){

for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){

Node nxt=u;

nxt.now[0]=e[i].to;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;

vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;

nxt.t=u.t+1;

q.push(nxt);

}

}else if(n==2){

for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){

Node nxt=u;

nxt.now[0]=e[i].to;

for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){

nxt.now[1]=e[j].to;

if(nxt.now[0]==nxt.now[1])  continue;

if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;

vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;

nxt.t=u.t+1;

q.push(nxt);

}

}

}else{

for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){

Node nxt=u;

nxt.now[0]=e[i].to;

for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){

nxt.now[1]=e[j].to;

if(nxt.now[0]==nxt.now[1])  continue;

if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;

for(int k=head[u.now[2]];k!=-1;k=e[k].nxt){

nxt.now[2]=e[k].to;

if(nxt.now[2]==nxt.now[0]||nxt.now[2]==nxt.now[1])  continue;

if(nxt.now[2]==u.now[0]&&nxt.now[0]==u.now[2])  continue;

if(nxt.now[2]==u.now[1]&&nxt.now[1]==u.now[2])  continue;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;

vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;

nxt.t=u.t+1;

q.push(nxt);

}

}

}

}

}

return -1;

}

int main(){

while(scanf("%d%d%d",&w,&h,&n) != EOF && (w || h || n)){

getchar();

for(int i = 0;i < h ; i++)      gets(mp[i]);

init();

printf("%d\n",bfs());

}

return 0;

}  

//双向bfs

#include<iostream>

#include<cstdio>

#include<queue>

#include<cstring>

#include<algorithm>

using namespace std;

struct Node{

int t,now[3];

Node(int _t,int a = -1,int b = -1,int c = -1):t(_t){

now[0] = a;now[1] = b;now[2]= c;

}

};

struct Edge{

int to,nxt;

};

Edge e[2000];

char mp[17][17];

int w,h,n,cnt,head[267];

int goal[3],start[3],vis[268][268][268];

int d[5][2] = {{0,0},{-1,0},{1,0},{0,1},{0,-1}};

void add(int u,int v){

e[cnt].to = v;

e[cnt].nxt = head[u];

head[u] = cnt++;

}

void init(){

cnt = 0;

memset(start,-1,sizeof(start));

memset(goal,-1,sizeof(goal));

memset(head,-1,sizeof(head));

for(int i = 0; i < h ;++i){

for(int j = 0;j < w;++j){

if(mp[i][j] == ‘#‘)     continue;

if(mp[i][j] >= ‘a‘ && mp[i][j] <= ‘c‘)

start[ mp[i][j] - ‘a‘ ] = i*w + j;

if(mp[i][j] >= ‘A‘ && mp[i][j] <= ‘C‘)

goal[ mp[i][j] - ‘A‘ ] = i*w + j;

for(int k = 0;k < 5;++k){

int ni = i + d[k][0],nj = j + d[k][1];

if(ni >= 0 && ni < h && nj >=0 && nj<w && mp[ni][nj]!=‘#‘)

add(i*w+j,ni*w+nj);

}

}

}

}

int bfs(){

queue<Node> q[2];

memset(vis,0,sizeof(vis));

vis[start[0]+10][start[1]+10][start[2]+10] = 1;

vis[goal[0]+10][goal[1]+10][goal[2]+10] = 2;

q[0].push(Node(0,start[0],start[1],start[2]));

q[1].push(Node(0,goal[0],goal[1],goal[2]));

int cur = 1,visflg[2] = {1,2};

while(!q[0].empty() || !q[1].empty()){

cur ^= 1;

int curct = q[cur].front().t;

while(!q[cur].empty() && q[cur].front().t == curct){

Node u = q[cur].front();q[cur].pop();

if(n==1){

for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){

Node nxt=u;

nxt.now[0]=e[i].to;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur^1])

return u.t + q[cur^1].front().t + 1;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur])    continue;

vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=visflg[cur];

nxt.t=u.t+1;

q[cur].push(nxt);

}

}else if(n==2){

for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){

Node nxt=u;

nxt.now[0]=e[i].to;

for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){

nxt.now[1]=e[j].to;

if(nxt.now[0]==nxt.now[1])  continue;

if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur^1])

return u.t + q[cur^1].front().t + 1;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur])    continue;

vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=visflg[cur];

nxt.t=u.t+1;

q[cur].push(nxt);

}

}

}else{

for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){

Node nxt=u;

nxt.now[0]=e[i].to;

for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){

nxt.now[1]=e[j].to;

if(nxt.now[0]==nxt.now[1])  continue;

if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;

for(int k=head[u.now[2]];k!=-1;k=e[k].nxt){

nxt.now[2]=e[k].to;

if(nxt.now[2]==nxt.now[0]||nxt.now[2]==nxt.now[1])  continue;

if(nxt.now[2]==u.now[0]&&nxt.now[0]==u.now[2])  continue;

if(nxt.now[2]==u.now[1]&&nxt.now[1]==u.now[2])  continue;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur^1])

return u.t + q[cur^1].front().t + 1;

if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur])    continue;

vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=visflg[cur];

nxt.t=u.t+1;

q[cur].push(nxt);

}

}

}

}

}

}

return -1;

}

int main(){

while(scanf("%d%d%d",&w,&h,&n) != EOF && (w || h || n)){

getchar();

for(int i = 0;i < h ; i++)      gets(mp[i]);

init();

printf("%d\n",bfs());

}

return 0;

}  

来自为知笔记(Wiz)

时间: 2024-10-05 18:07:56

[2016-02-24][UVA][1601][The Morning after Halloween]的相关文章

2016/02/24 codes

CrossVF:function (s){var tX = this.x;x.this = s * this.y;this.y = -s * tX;}, CrossFV:function (s){var tX = this.x;this.x = -s * this.y;this.y = s * tX;}, minV:function(b){this.x = this.x < b.x ? this.x: b.x;this.y = this.y < b.y ? this.y: b.y;}, max

2016.02.24总结

今天学习了JavaOO上册中的第8章,类的高级概念,其中的要点有: 1. 动态绑定:父类的引用可以指向子类的对象,但只能用子类中的父类部分的属性和方法. 2. 访问修饰符(可用于修饰属性,方法,类): private:只能用在本类中: 默认访问修饰符:可以用在本类,同包的子类和非子类中: protected:可以用在本类,同包的子类和非子类,以及不同包的子类中: public:可以用在所有类中. 3. OOP的封装就是通过访问修饰符来实现的,一般类中属性都设为私有的,并通过编写相应的getter

UVA 1601 The Morning after Halloween(搜索,二维数组转为图)

学习: 转化成图 1 //#include<bits/stdc++.h> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 typedef long long ll; 7 int n,m,k; 8 char maps[20][20]; 9 int vis[200][200][200]; 10 int num[20][20]; 11 int

uva 1601 The Morning after Halloween

题意: 一张图,有空格,有障碍,有字母 每秒钟每个字母可以移动到相邻非障碍格 问所有的小写字母移动到大写字母所需的最少时间 https://vjudge.net/problem/UVA-1601 预处理每个状态有哪些后继状态 #include<queue> #include<cstdio> #include<cstring> #include<iostream> using namespace std; int m,n,p,s[3],t[3]; int dx

分布式技术一周技术动态 2016.02.21

分布式系统实践 1. 远程接口设计经验分享 http://mp.weixin.qq.com/s?__biz=MzAwNjQwNzU2NQ%3D%3D&idx=2&mid=402064901&scene=0&sn=0b5f56a97b431ed355b75a9e17f2e754 要点: 分布式系统由于中间存在网络因素, 出错的情况比单机系统要多很多, 那么如何设计一个远程接口呢? 本文很好的解释了设计远程接口需要考虑的问题点. 2. 时序列数据库武斗大会之什么是TSDB ht

2016/02/21 codes

var Class = { create:function(){ var parent = null,properties = $A(arguments); if(Object.isFunction(properties[0])) parent = properties.shift(); function kclass(){ this.initialize.apply(this.arguments); } Object.extend(kclass,Class.Methods); kclass.s

FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM

FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM T.. = Timeline support 支持时间轴 .S. = Slice threading 分段线程 ..C = Command support 支持命令传送 A = Audio input/output 音频 输入/输出 V = Video input/output 视频 输入/输出 N = Dynamic number and/or type of input/out

2016/02/20 codes

<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>2016/02/20</title></head><body><div id="mainDiv"> <div id = "content"> <div id = &qu

2016/02/16 codes

<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>2016/02/16 codes</title> <link rel="stylesheet" href="assets/reset.css"> <style> .slideOne{ width: