您的位置:首页 > 其它

uva 1601 The Morning after Halloween

2017-08-18 20:40 288 查看
题目:The Morning after Halloween

题意:有n个用小写字母表示的鬼和一张地图,每个鬼都要移动到对应的大写字母,两个鬼的位置不能在一次移动中交换,问最少步数。

思路:

bfs。

1、先将地图用图的方法表示,即在每一个空白(包括大小写字母)和四周的空白连上一条边,用单个整数表示一个空白。

2、在图上进行bfs。注意只有一个鬼的情况,此时鬼b和鬼c所在的位置都用0表示可能会相等而判定它们在同一位置,实际根本不存在这俩鬼。如以下数据:

/*
5 5 1
#####
#A# #
# #
# #a#
#####
0 0 0
*/

ps:样例数据粘贴过来少了几个空格……此格式正确的样例:
/*
5 5 2
#####
#A#B#
# #
#b#a#
#####
16 4 3
################
## ########## ##
# ABCcba #
################
16 16 3
################
### ## # ##
## # ## # c#
# ## ########b#
# ## # # # #
# # ## # # ##
## a# # # # #
### ## #### ## #
## # # # #
# ##### # ## ##
#### #B# # #
## C# # ###
# # # ####### #
# ###### A## #
# # ##
################
*/

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<sstream>
#include<queue>
using namespace std;

#define N 20
#define Num 3
#define m_step 200

int n,m,num;
int Start[Num],End[Num];
vector<int> g[N*N];
int cnt=0;
int step[m_step][m_step][m_step];

struct Node {
int x[Num];
Node() {}
Node(int xx[]) {
for(int i=0; i<num; i++) x[i]=xx[i];
}
Node(int one,int two,int three){
x[0]=one,x[1]=two,x[2]=three;
}
bool operator ==(const Node& other) const{
for(int i=0;i<num;i++){
if(x[i]!=other.x[i]) return false;
}
return true;
}
void print(){
printf("(%d,%d,%d) %d\n",x[0],x[1],x[2],step[x[0]][x[1]][x[2]]);
}
};

void init() {
cnt=0;
for(int i=0; i<N*N; i++) g[i].clear(),g[i].push_back(i);
memset(step,-1,sizeof(step));
memset(Start,0,sizeof(Start));
memset(End,0,sizeof(End));
}

void make_G(char a

) {
int fill

= {0};
memset(fill,0,sizeof(fill));
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(a[i][j]!='#') {
fill[i][j]=++cnt;
if(i!=0&&a[i-1][j]!='#') g[cnt].push_back(fill[i-1][j]),g[fill[i-1][j]].push_back(cnt);
if(j!=0&&a[i][j-1]!='#') g[cnt].push_back(fill[i][j-1]),g[fill[i][j-1]].push_back(cnt);
}
}
}
int S[26]= {0},E[26]= {0};
memset(S,0,sizeof(S));
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if('A'<=a[i][j]&&a[i][j]<='Z') {
E[a[i][j]-'A']=fill[i][j];
}
if('a'<=a[i][j]&&a[i][j]<='z') {
S[a[i][j]-'a']=fill[i][j];
}
}
}
int s=-1;
for(int i=0; i<26; i++) {
if(S[i]) {
++s;
Start[s]=S[i];
End[s]=E[i];
}
}
}

void bfs() {
Node IN=Node(Start),OUT=Node(End);
queue<Node> que;
que.push(IN);
step[IN.x[0]][IN.x[1]][IN.x[2]]=0;
while(!que.empty()) {
Node head=que.front();
que.pop();
int a=head.x[0],b=head.x[1],c=head.x[2];
if(head==OUT) {
printf("%d\n",step[a][b][c]);
return;
}
for(int i=0; i<g[a].size(); i++) {
for(int j=0; j<g[b].size(); j++) {
if(g[a][i]==g[b][j]||(a==g[b][j]&&b==g[a][i])) continue;
for(int k=0; k<g[c].size(); k++) {
if((g[a][i]==g[c][k]||g[c][k]==g[b][j]||(a==g[c][k]&&c==g[a][i])||(b==g[c][k]&&c==g[b][j]))&&c!=0) continue;
if(step[g[a][i]][g[b][j]][g[c][k]]==-1){
step[g[a][i]][g[b][j]][g[c][k]]=step[a][b][c]+1;
que.push(Node(g[a][i],g[b][j],g[c][k]));
}
}
}
}
}
}

int main() {
while(scanf("%d%d%d",&m,&n,&num)==3&&n&&m&&num) {
init();
char a

;
for(int i=0; i<n; i++) {
getchar();
fgets(a[i],m+1,stdin);
}
make_G(a);
bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva bfs 暴力