zoukankan      html  css  js  c++  java
  • 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
    "); 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
    ",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();
        } 
    } 
  • 相关阅读:
    OpenCv 014---图像插值(Image interpolation)
    基础正则
    Base -快捷键|通配符|特殊符号|输出(正确与错误的保存)
    linux 软链接 硬链接
    shell 别名alias
    yii2 源码分析1从入口开始
    php const static define 基本用法和区别
    php-fpm, nginx ,fastcgi ,php-cgi 关系粗解
    php扩展开发3--扩展类传参数
    php扩展开发2--添加类
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7281322.html
Copyright © 2011-2022 走看看