HDU2821Pusher(BFS+枚举)

Pusher

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/65536 K (Java/Others)

Total Submission(s): 903    Accepted Submission(s): 327

Special Judge

Problem Description

PusherBoy is an online game http://www.hacker.org/push . There is an R * C grid, and there are piles of blocks on some positions. The goal is to clear the blocks by pushing into them.

You should choose an empty area as the initial position of the PusherBoy. Then you can choose which direction (U for up, D for down, L for left and R for right) to push. Once the direction is chosen, the PusherBoy will walk ahead until he met a pile of blocks
(Walking outside the grid is invalid). Then he remove one block from the pile (so if the pile contains only one block, it will become empty), and push the remaining pile of blocks to the next area. (If there have been some blocks in the next area, the two
piles will form a new big pile.)

Please note if the pusher is right up against the block, he can‘t remove and push it. That is, there must be a gap between the pusher and the pile. As the following figure, the pusher can go up, but cannot go down. (The cycle indicates the pusher, and the squares
indicate the blocks. The nested squares indicate a pile of two blocks.)

And if a whole pile is pushed outside the grid, it will be considered as cleared.

Input

There are several test cases in each input. The first two lines of each case contain two numbers C and R. (R,C <= 25) Then R lines follow, indicating the grid. ‘.‘ stands for an empty area, and a lowercase letter stands for a pile
of blocks. (‘a‘ for one block, ‘b‘ for two blocks, ‘c‘ for three, and so on.)

Output

Output three lines for each case. The first two lines contains two numbers x and y, indicating the initial position of the PusherBoy. (0 <= x < R, 0 <= y < C). The third line contains a moving sequence contains ‘U‘, ‘D‘, ‘L‘ and ‘R‘.
Any correct answer will be accepted.

Sample Input

3
7
...
...
.b.
...
...
.a.
...

Sample Output

4
1
UDU

Hint

Hint: The following figures show the sample. The circle is the position of the pusher.
And the squares are blocks (The two nested squares indicating a pile of two blocks). And this is the unique solution for this case.


 

Source

2009 Multi-University Training Contest 1 - Host by TJU

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;

struct node
{
    int sx,sy;
    int x,y,n,blocksNumb;
    char path[200];
    char map[25][25];
};
char map[27][27];
int R,C,dir[4][2]={-1,0,1,0,0,-1,0,1};
char dirChar[4]={'U','D','L','R'};

int judge(node &tp,int e)
{
    tp.path[tp.n]=dirChar[e];
    tp.path[tp.n+1]='\0';
    tp.n++;
    tp.x=tp.x+dir[e][0];
    tp.y=tp.y+dir[e][1];
    if(tp.map[tp.x][tp.y]!='.')
        return 0;
    while(true)
    {
        tp.x=tp.x+dir[e][0];
        tp.y=tp.y+dir[e][1];
        if(tp.x<0||tp.x>=R||tp.y<0||tp.y>=C)
            return 0;
        if(tp.map[tp.x][tp.y]!='.')
        {
            if(tp.map[tp.x][tp.y]>'a')
            {
                tp.map[tp.x][tp.y]-=1;
                tp.blocksNumb--;
                int x=tp.x+dir[e][0];
                int y=tp.y+dir[e][1];
                if(x>=0&&x<R&&y>=0&&y<C)
                {
                    if(tp.map[x][y]=='.')
                        tp.map[x][y]=tp.map[tp.x][tp.y];
                    else
                        tp.map[x][y]+=tp.map[tp.x][tp.y]-'a'+1;
                }
                else
                    tp.blocksNumb-=tp.map[tp.x][tp.y]-'a'+1;
            }
            else
                tp.blocksNumb--;
            tp.map[tp.x][tp.y]='.';
            return 1;
        }
    }
}
void bfs()
{
    queue<node>q;
    node p,tp,pp;
    int blocksNumb=0;

    for(int i=0;i<R;i++)
        for(int j=0;j<C;j++)
        {
            pp.map[i][j]=map[i][j];
            if(map[i][j]!='.')
            blocksNumb+=map[i][j]-'a'+1;
        }
    pp.blocksNumb=blocksNumb;
    pp.n=0;
    for(int i=0;i<R;i++)
        for(int j=0;j<C;j++)
        if(map[i][j]=='.') //枚举每个起始位置
        {
            pp.sx=i; pp.sy=j;
            pp.x= i; pp.y= j;
            q.push(pp);
            while(!q.empty())
            {
                p=q.front(); q.pop();
                for(int e=0;e<4;e++)
                {
                    tp=p;
                    if(judge(tp,e))
                    {
                        if(tp.blocksNumb==0)
                        {
                            printf("%d\n%d\n%s\n",tp.sx,tp.sy,tp.path); return ;
                        }
                        q.push(tp);
                    }
                }
            }
        }
}
int main()
{
    while(scanf("%d%d",&C,&R)>0)
    {
        for(int i=0;i<R;i++)
            scanf("%s",map[i]);
        bfs();
    }
}
时间: 2024-11-07 12:29:47

HDU2821Pusher(BFS+枚举)的相关文章

【UVa10606】Mines For Diamonds 题解(bfs+枚举)

传送门:https://uva.onlinejudge.org/external/106/10605.pdf 题目大意:给你一个N * M的矩阵,一些格子中分布着钻石(地雷),需要找到若干条不分岔的从边界开始延伸的道路,可以覆盖所有的钻石.求这些道路覆盖的最小方格数.下图中的答案为11. 看到题首先想到用bfs预处理出每对钻石之间的距离以及每个钻石到边界的最短距离,这个可以由对每个钻石bfs求出. 接下来枚举钻石的排列,枚举出来排列之后就可以贪心扫一遍了.具体来说,依次考虑每个钻石,对于一个钻石

poj 1753 Flip Game (bfs + 枚举)

链接:poj 1753 题意:这是翻棋游戏,给定4*4棋盘,棋子一面为黑色(用b表示),另一面为白色(用w表示),问至少要几步可以将棋子翻为全黑或者全白,如不能达到目的,输出"Impossible " 翻转规则:可以选定16个棋子中的任意一个,将其本身以及上下左右相邻的翻转过来 分析:其实每格棋子最多只可以翻转一次(实际是奇数次,但与翻转一次状态一样),只要其中一格重复翻了2次(不论是连续翻动还是不连翻动),那么它以及周边的棋子和没翻动时的状态是一致的,与最初状态未翻转一样,由此就可以

hdu 4400 Mines(离散化+bfs+枚举)

Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all people in time before any mine explodes. Now the police want all the mines be ignited. The police will take many operations to do the job. In each ope

HDU 1973 Prime path(BFS+素数表)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1973 题目大意:给定两个四位素数a  b,要求把a变换到b变换的过程要保证  每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数 与前一步得到的素数  只能有一个位不同,而且每步得到的素数都不能重复.求从a到b最少需要的变换次数.无法变换则输出Impossible. 如下面的样例:1033 8179 1033 1733 3733 3739 3779 8779 8179 所以答案为6.

POJ1753 状态压缩(+BFS) + 棋盘问题

0 棋盘问题,改变一个子的颜色,这个子以及这个子周围的四个位置(左右上下)的子分别变色,求最少的改变次数. 此类题大部分应该可以用状态压缩+暴力搜索解决.纯粹找规律不太合理. 1)第一种方法,状态压缩后BFS暴力搜索.因为棋盘很小,只有16个格子,枚举所有的状态共有2^16=65536种.所以有可以用int数组存储65535个状态用以确认哪一个出现了哪一个没出现,然后暴力枚举+BFS的搜索方式. 2)第二种,或者不进行状态压缩,直接按顺序,确定改变次数为1.改变次数为2...改变次数为16,在每

POJ3026(BFS + prim)

Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10554   Accepted: 3501 Description The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to desc

Codeforces Round #292 (Div. 2)

换了新ID,以前的ID 运气不好 D:题目隐藏的很深啊!如果说拓扑排序肯定会写,模型转换. 计算每个点'.'的度,度:周围4个点为'.'的数目. 然后BFS 枚举度为1的点 ,一遍构造,链接的点就度--: 再压入队列中 当枚举的点数不够'.'数目时,答案就是'unique'; 题目没要你输出any 这本身有蹊跷. #include <stdio.h> #include <string.h> #include <iostream> #include <algorit

概率论 --- Uva 11181 Probability|Given

Uva 11181 Probability|Given Problem's Link:   http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18546 Mean: n个人去逛超市,第i个人会购买东西的概率是Pi.出超市以后发现有r个人买了东西,问你每个人购买东西的实际概率是多少. analyse: 转换模型: 有n个员工,每个员工被选出来的概率是Pi.最后选出了r个,问你第i个员工在这r个中的概率是多少. 设: 事件A---

【POJ1753】Flip Game

[题目大意] 有一个4x4规格的一个棋盘,现在有16个一面黑一面白的棋子分布在这个棋盘上. 翻转一个棋子能够使它以及它上下左右的四个棋子从黑变白,从白变黑. 现在问你至少要经过多少次操作才能够使得整个棋盘的颜色相同. [分析] 考虑到是4x4的规模,想到用BFS枚举+判重. 注意题目的内存限制是64MB,如果普通的用一个二维数组记录状态可能会超过内存限制. 考虑位运算,下面给出AC代码. 1 #include <iostream> 2 #include <fstream> 3 #i