首页 > 代码库 > 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