The Morning after Halloween uva1601

这道题思路还是比较清晰的,建图加bfs或双向bfs,其实后者比前者少了将近一半的时间。。

建图可以把某一点所拥有邻接点长度(数目)记录在数组0这个位置,因为这道题使用vector会超时。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
using namespace std;
char a[17][17];
int nex[4][2]= {1,0,0,1,-1,0,0,-1};
int book[17][17],top,book1[400];
int w,h,n;
int sta[3],ent[3];
int mat[400][400];
inline bool is_inrage(int x,int y)
{
    if(x<0||x>=h||y<0||y>=w) return false;
    return true;
}
int findid(int x,int y)
{
    if(book[x][y]) return book[x][y];
    book[x][y]=++top;
    return book[x][y];
}
struct note
{
    int status[3];
    int length;
    int step;
    note()
    {
        status[0]=status[1]=status[2]=0;
    }
};
short vis1[400][400][400],vis2[400][400][400];
bool invilid(int prea,int preb,int nowa,int nowb)
{
    if(nowa==nowb||(prea==nowb&&preb==nowa)) return true;
    return false;
}
int bfs(int len)
{
    memset(vis1,0,sizeof(vis1));
    memset(vis2,0,sizeof(vis2));
    queue<note>que1,que2;
    note start,ends;
    ends.length=start.length=len;
    ends.step=start.step=0;
    for(int i=0; i<len; i++)
    {
        start.status[i]=sta[i];
        ends.status[i]=ent[i];
    }
    que1.push(start);
    que2.push(ends);
    vis1[start.status[0]][start.status[1]][start.status[2]]=1;
    vis2[ends.status[0]][ends.status[1]][ends.status[2]]=1;
    int ac[3],flag;
    struct note u1,v1,u2,v2;
    while(!que1.empty()||!que2.empty())
    {
        if(!que1.empty())
        {
            u1=que1.front();
            que1.pop();
            for(int i=1; i<=mat[u1.status[0]][0]; i++)
            {
                ac[0]=mat[u1.status[0]][i];
                for(int j=1; j<=mat[u1.status[1]][0]; j++)
                {
                    ac[1]=mat[u1.status[1]][j];
                    if(invilid(u1.status[0],u1.status[1],ac[0],ac[1])) continue;
                    for(int h=1; h<=mat[u1.status[2]][0]; h++)
                    {
                        ac[2]=mat[u1.status[2]][h];
                        if(len==3) if(invilid(u1.status[0],u1.status[2],ac[0],ac[2])) continue;
                        if(len==3) if(invilid(u1.status[1],u1.status[2],ac[1],ac[2])) continue;
                        v1.step=u1.step+1;
                        v1.length=u1.length;
                        v1.status[0]=ac[0];
                        v1.status[1]=ac[1];
                        v1.status[2]=ac[2];
                        if(vis1[v1.status[0]][v1.status[1]][v1.status[2]]) continue;
                        vis1[v1.status[0]][v1.status[1]][v1.status[2]]=v1.step;
                        que1.push(v1);
                        int a1,b1,c1;
                        a1=v1.status[0];b1=v1.status[1];c1=v1.status[2];
                        if(vis2[a1][b1][c1]) return vis1[a1][b1][c1]+vis2[a1][b1][c1];
                    }
                }
            }
        }
        if(!que2.empty())
        {
            u2=que2.front();
            que2.pop();
            for(int i=1; i<=mat[u2.status[0]][0]; i++)
            {
                ac[0]=mat[u2.status[0]][i];
                for(int j=1; j<=mat[u2.status[1]][0]; j++)
                {
                    ac[1]=mat[u2.status[1]][j];
                    if(invilid(u2.status[0],u2.status[1],ac[0],ac[1])) continue;
                    for(int h=1; h<=mat[u2.status[2]][0]; h++)
                    {
                        ac[2]=mat[u2.status[2]][h];
                        if(len==3) if(invilid(u2.status[0],u2.status[2],ac[0],ac[2])) continue;
                        if(len==3) if(invilid(u2.status[1],u2.status[2],ac[1],ac[2])) continue;
                        v2.step=u2.step+1;
                        v2.length=u2.length;
                        v2.status[0]=ac[0];
                        v2.status[1]=ac[1];
                        v2.status[2]=ac[2];
                        if(vis2[v2.status[0]][v2.status[1]][v2.status[2]]) continue;
                        vis2[v2.status[0]][v2.status[1]][v2.status[2]]=v2.step;
                        que2.push(v2);
                        int a2,b2,c2;
                        a2=v2.status[0];b2=v2.status[1];c2=v2.status[2];
                        if(vis1[a2][b2][c2]) return vis1[a2][b2][c2]+vis2[a2][b2][c2];
                    }
                }
            }
        }
    }
    return -1;
}
struct node
{
    int x,y;
    char v;
    node() {}
    node(int xx,int yy,char vv):x(xx),y(yy),v(vv) {}
    bool operator < (const node &another) const
    {
        return v<another.v;
    }
};
int main()
{
    while(scanf("%d%d%d",&w,&h,&n),w+h+n)
    {
        char ch[20];
        memset(book,0,sizeof(book));
        node t1[3],t2[3];
        int s1=0,s2=0;
        memset(mat,0,sizeof(mat));
        getchar();
        for(int i=0; i<h; i++)
        {
            gets(ch);
            for(int j=0; j<w; j++)
            {
                a[i][j]=ch[j];
                if(‘a‘<=ch[j]&&ch[j]<=‘z‘)  t1[s1++]=node(i,j,ch[j]);
                if(‘A‘<=ch[j]&&ch[j]<=‘Z‘)  t2[s2++]=node(i,j,ch[j]);
            }
        }
        int nx,ny,idpre,idnex;
        top=0;
        for(int i=0; i<h; i++)
        {
            for(int j=0; j<w; j++)
            {
                for(int k=0; k<4; k++)
                {
                    if(a[i][j]==‘#‘) continue;
                    nx=i+nex[k][0];
                    ny=j+nex[k][1];
                    if(is_inrage(nx,ny)&&a[nx][ny]!=‘#‘)
                    {
                        idpre=findid(i,j);
                        idnex=findid(nx,ny);
                        int lenth=++mat[idpre][0];
                        mat[idpre][lenth]=idnex;
                    }
                }
            }
        }
        for(int i=0; i<=top; i++)
        {
            ++mat[i][0];
            mat[i][mat[i][0]]=i;
        }
        sort(t1,t1+n);
        sort(t2,t2+n);
        for(int i=0; i<n; i++)
        {
            sta[i]=findid(t1[i].x,t1[i].y);
            ent[i]=findid(t2[i].x,t2[i].y);
   //         cout<<sta[i]<<" "<<ent[i]<<endl;
        }
        printf("%d\n",bfs(n));
    }
    return 0;
}
时间: 2025-01-04 22:55:18

The Morning after Halloween uva1601的相关文章

UVa1601 The Morning after Halloween (双向广度优先搜索)

链接:http://acm.hust.edu.cn/vjudge/problem/51163分析:已知起点和终点可以利用双向广度优先搜索,正向扩展一层,反向扩展一层,为防止退化,优先扩展结点数多的方向.因为障碍物很多防止TLE,可以先把图除了‘#’抠下来,用cnt给位置编号,x[cnt],y[cnt]为编号为cnt的格子的横纵坐标,id记录坐标为x,y格子的编号,然后找这些格子周围能走的格子,用deg[cnt]保存编号为cnt的格子周围能走的格子数,用G[cnt][i]保存编号为cnt的格子周围

UVa1601 - The Morning after Halloween(单向+双向BFS)

给出一个最大为16×16的迷宫图和至多3个ghost的起始位置和目标位置,求最少经过几轮移动可以使三个ghost都到达目标位置.每轮移动中,每个ghost可以走一步,也可以原地不动,需要注意的是任意两个ghost不能在相同的位置,因此也不能出现任意两个ghost对穿,也就是原来是ab,移动之后是ba.每个迷宫图'#'表示墙,' '表示空地,小写字母表示ghost的起始位置,大写字母表示对应ghost的目标位置,比如'a'应该走到'A'.保证任意2×2的空间内都有一个'#'. 看起来就像是人数多了

UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS &amp;&amp; 降维 &amp;&amp; 状压)

题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占用同一个位置,也不能在一步之内交换位置.输入保证所有空格连通,所有障碍格也连通,且任何一个2*2子网格中至少有一个障碍格.输出最少的步数.输入保证有解. 分析 :可以将当前所有小鬼的位置作为一个状态,然后模拟小鬼移动BFS拓展出其他可行状态并且顺带记录步数,直到所有的小鬼都到达终点.首先状态如何表示

Halloween Costumes LightOJ - 1422

Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is planning to attend as many parties as he can. Since it's Halloween, these parties are all costume parties, Gappu always selects his costumes in such a way that

POJ 3370 Halloween treats(抽屉原理)

Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6631   Accepted: 2448   Special Judge Description Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets

How to obtain free runescape eoc to 07 gold from RSorder as Halloween gift 10.31?

Follow these steps in order, where practical. {Click runescape 2007 gold sequences are shown for Windows XP Professional and are only meant to be a general guide}.Make Some BackupsYou need a fall back position in case bad things happen. Create an XP

POJ 3370 Halloween treats(抽屉原理)

题意  有c个小孩 n个大人万圣节搞活动  当小孩进入第i个大人家里时   这个大人就会给小孩a[i]个糖果  求小孩去哪几个大人家可以保证得到的糖果总数是小孩数c的整数倍  多种方案满足输出任意一种 用s[i]表示前i个打人给糖果数的总和  令s[0]=0  那么s[i]共有n+1种不同值  而s[i]%c最多有c种不同值  题目说了c<=n   所以s[i]%c肯定会有重复值了 这就是抽屉原理了   n个抽屉放大于n个苹果   至少有一个抽屉有大于等于2个苹果 就把s[i]%c的取值个数(c

LigntOj1422 Halloween Custumes

题意:n天,每天穿哪件衣服有要求,衣服可以套着穿,但是脱下来的衣服就不能再穿了,问最少要准备多少件衣服 题解:这是到区间DP,也算是我的第一道区间DP F[ i ][ j ] 表示从第 i 天到第 j 天最少要几件衣服. 倒着推,我们考虑需不需要第 ai 件衣服,有两种情况:① 需要,那么F[ i ][ j ] = F[ i + 1][ j ] + 1; ② 不需要,那么就在 i + 1 到 j 天找有没有和第 i 天穿的衣服一样的,有那么 F[ i ][ j ] = F[ i + 1][ k

poj 3370 Halloween treats(鸽巢原理)

Description Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets on that day, no matter how many children call on him, so it may happen that a child will get nothing if it is too l