首页 > 代码库 > uva 1601 The Morning after Halloween
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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。