uva 1601 The Morning after Halloween
Posted 日拱一卒 功不唐捐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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[5]={0,-1,0,1,0},dy[5]={0,0,1,0,-1}; int id[17][17],cnt,x[200],y[200],can[200][7]; int dis[200][200][200]; bool a[17][17]; string ss; struct node { int a,b,c; bool operator == (node q) const { return a==q.a && b==q.b && c==q.c; } }now,nxt; queue<node>q; void init() { cnt=0; memset(a,false,sizeof(a)); for(int i=1;i<=n;i++) { getline(cin,ss); for(int j=0;j<m;j++) { if(ss[j]!=‘#‘) x[++cnt]=i,y[cnt]=j+1,id[i][j+1]=cnt; else a[i][j+1]=true; if(islower(ss[j])) s[ss[j]-‘a‘]=cnt; else if(isupper(ss[j])) t[ss[j]-‘A‘]=cnt; } } } void pre() { memset(can,0,sizeof(can)); int nx,ny; for(int i=1;i<=cnt;i++) for(int j=0;j<5;j++) { nx=x[i]+dx[j]; ny=y[i]+dy[j]; if(nx<1 || nx>n || ny<1 || ny>m || a[nx][ny]) continue; can[i][++can[i][0]]=id[nx][ny]; } if(p<=2) can[++cnt][++can[cnt][0]]=cnt,s[2]=t[2]=cnt; if(p<=1) can[++cnt][++can[cnt][0]]=cnt,s[1]=t[1]=cnt; } void solve() { while(!q.empty()) q.pop(); memset(dis,-1,sizeof(dis)); node last; last.a=t[0]; last.b=t[1]; last.c=t[2]; dis[s[0]][s[1]][s[2]]=0; now.a=s[0]; now.b=s[1]; now.c=s[2]; if(now==last) { printf("0\n"); return; } q.push(now); int na,nb,nc; while(!q.empty()) { now=q.front(); q.pop(); na=now.a; nb=now.b; nc=now.c; for(int i=1;i<=can[na][0];i++) { for(int j=1;j<=can[nb][0];j++) { if(can[na][i]==can[nb][j]) continue; if(na==can[nb][j] && nb==can[na][i]) continue; for(int k=1;k<=can[nc][0];k++) { if(can[na][i]==can[nc][k] || can[nb][j]==can[nc][k]) continue; if(na==can[nc][k] && nc==can[na][i] || nb==can[nc][k] && nc==can[nb][j]) continue; if(dis[can[na][i]][can[nb][j]][can[nc][k]]!=-1) continue; nxt.a=can[na][i]; nxt.b=can[nb][j]; nxt.c=can[nc][k]; if(nxt==last) { printf("%d\n",dis[na][nb][nc]+1); return; } dis[nxt.a][nxt.b][nxt.c]=dis[na][nb][nc]+1; q.push(nxt); } } } } } int main() { char y; while(scanf("%d%d%d",&m,&n,&p)!=EOF) { if(!m) return 0; y=getchar(); init(); pre(); solve(); } }
以上是关于uva 1601 The Morning after Halloween的主要内容,如果未能解决你的问题,请参考以下文章
UVa1601 The Morning after Halloween(双向bfs)
The Morning after Halloween uva1601
UVA - 1601 - The Morning after Halloween
UVa1601 The Morning after Halloween (双向广度优先搜索)
UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)