HDU-2821-Pusher(DFS)

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

思路:简单DFS。给若干个可重叠的格子,起点可以任意选择,可以往四个方向一直走到有格子的地方为止,每碰一次就消掉一个格子,并且把剩下的移到下一个位置。

注意:①起点不能有格子。②必须要隔一个位置才能碰。③碰的格子在边上时,剩下的格子不能移出矩形范围。④格子在边上时,碰之后如果还有格子剩余,pusher的位置就不在边上,否则就在边上。

#include <stdio.h>

int n,m,total,sx,sy;
char mp[25][26],ans[10000];
bool flag;

void dfs(int x,int y,int cnt)
{
    int i,t1,t2;

    if(flag) return;

    if(cnt==total)
    {
        printf("%d\n%d\n",sx,sy);

        ans[cnt]=0;

        puts(ans);

        flag=1;

        return;
    }

    if(x-1>0 && !mp[x-1][y])//U
    {
        for(i=x-2;i>=0;i--) if(mp[i][y]>0) break;

        if(i>0)
        {
            t1=mp[i-1][y];
            t2=mp[i][y];
            mp[i-1][y]+=mp[i][y]-1;
            mp[i][y]=0;

            ans[cnt]='U';

            dfs(i,y,cnt+1);

            mp[i-1][y]=t1;
            mp[i][y]=t2;
        }
        else if(!i)
        {
            mp[i][y]--;

            ans[cnt]='U';

            if(mp[i][y]) dfs(1,y,cnt+1);
            else dfs(0,y,cnt+1);

            mp[i][y]++;
        }
    }

    if(y-1>0 && !mp[x][y-1])//L
    {
        for(i=y-2;i>=0;i--) if(mp[x][i]>0) break;

        if(i>0)
        {
            t1=mp[x][i-1];
            t2=mp[x][i];
            mp[x][i-1]+=mp[x][i]-1;
            mp[x][i]=0;

            ans[cnt]='L';

            dfs(x,i,cnt+1);

            mp[x][i-1]=t1;
            mp[x][i]=t2;
        }
        else if(!i)
        {
            mp[x][i]--;

            ans[cnt]='L';

            if(mp[x][i]) dfs(x,1,cnt+1);
            else dfs(x,0,cnt+1);

            mp[x][i]++;
        }
    }

    if(y+1<m-1 && !mp[x][y+1])//R
    {
        for(i=y+2;i<m;i++) if(mp[x][i]>0) break;

        if(i<m-1)
        {
            t1=mp[x][i+1];
            t2=mp[x][i];
            mp[x][i+1]+=mp[x][i]-1;
            mp[x][i]=0;

            ans[cnt]='R';

            dfs(x,i,cnt+1);

            mp[x][i+1]=t1;
            mp[x][i]=t2;
        }
        else if(i==m-1)
        {
            mp[x][i]--;

            ans[cnt]='R';

            if(mp[x][i]) dfs(x,m-2,cnt+1);
            else dfs(x,m-1,cnt+1);

            mp[x][i]++;
        }
    }

    if(x+1<n-1 && !mp[x+1][y])//D
    {
        for(i=x+2;i<n;i++) if(mp[i][y]>0) break;

        if(i<n-1)
        {
            t1=mp[i+1][y];
            t2=mp[i][y];
            mp[i+1][y]+=mp[i][y]-1;
            mp[i][y]=0;

            ans[cnt]='D';

            dfs(i,y,cnt+1);

            mp[i+1][y]=t1;
            mp[i][y]=t2;
        }
        else if(i==n-1)
        {
            mp[i][y]--;

            ans[cnt]='D';

            if(mp[i][y]) dfs(n-2,y,cnt+1);
            else dfs(n-1,y,cnt+1);

            mp[i][y]++;
        }
    }
}

int main()
{
    int i,j;

    while(~scanf("%d%d",&m,&n))
    {
        for(i=0;i<n;i++) scanf("%s",mp[i]);

        total=flag=0;

        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(mp[i][j]!='.')
                {
                    total+=mp[i][j]-'a'+1;

                    mp[i][j]=mp[i][j]-'a'+1;
                }
                else mp[i][j]=0;
            }
        }

        for(i=0;i<n && !flag;i++)
        {
            for(j=0;j<m && !flag;j++)
            {
                if(!mp[i][j])
                {
                    sx=i;
                    sy=j;
                    dfs(i,j,0);
                }
            }
        }
    }
}

HDU-2821-Pusher(DFS),布布扣,bubuko.com

时间: 2024-12-15 01:38:50

HDU-2821-Pusher(DFS)的相关文章

HDU 4921 Map DFS+状态压缩+乘法计数

算最多十条链,能截取某前缀段,每种方案都可以算出一个权值,每种方案的概率都是总数分之一,问最后能构成的所有可能方案数. 对计数原理不太敏感,知道是DFS先把链求出来,但是想怎么统计方案的时候想了好久,其实因为只能取某个链的前缀,所以直接取链长加+1 然后相乘即可,当然因为会出现都是空的那种情况,要去掉,全部乘完之后,要-1 然后就是算权值了,权值等于当前加进来的点的总和 以及 等级相同的点的加成,并不是特别好算,这时候考虑每个状态下的点对全局的贡献,对,就是这个思想,用状态压缩来表示状态,然后这

(dfs) hdu 2821

Pusher Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/65536 K (Java/Others)Total Submission(s): 956    Accepted Submission(s): 348Special Judge Problem Description PusherBoy is an online game http://www.hacker.org/push . There is an R

hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c,s,flag; int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; char mapp[25][25],road[1000],d[5] = {"DURL"}; bool check(int x,int y) { if(x < 0 || x &g

HDU 1175 连连看(DFS)

Problem Description “连连看”相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过.玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

hdu 1501 Zipper dfs

题目链接: HDU - 1501 Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.For examp

HDU - 1175 连连看 DFS (记录方向)

连连看HDU - 1175 "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过. 玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

hdu 1455 Sticks——dfs经典的题目

http://acm.hdu.edu.cn/showproblem.php?pid=1455 题意:几根长度的棍子被分成了很多半.问合成多个长度相同的棍子,棍子长度最小是多少. 题解:很明显是dfs.所以我们首先需要找到,这些棍子可能是多长,肯定是最长的棍子的长度到所有棍子长度和之间的某个长度.找到这些可能之后就直接按照这个长度开始搜.想法是搜到和为这个长度之后记录,然后重新再搜,一直到所有棍子都分配自后就完成了. 重要的剪枝:确定每次搜索的起始位置,这个一定是确定的!!!其次就是相同长度的棍子

hdu 1241Oil Deposits(dfs模板)

题目链接—— http://acm.hdu.edu.cn/showproblem.php?pid=1241 首先给出一个n*m的字符矩阵,‘*’表示空地,‘@’表示油井.问在这个矩阵中有多少组油井区? 每个点周围的8个点都可以与之相连. 从左上角的点开始向后枚举然后dfs搜索就可以了.记得记忆化. 废话说完,上代码—— 1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <a

hdu 5798 Stabilization(dfs+巧妙利用二进制位)

题目链接:hdu 5798 Stabilization 题意: 给出一个序列Ai,可以让每个Ai异或上一个x使得最小,问最小值以及使得该值最小的最小x值 题解: 首先枚举x,然后如何来算得出的价值呢,巧妙的利用A[i]与A[i-1]的二进制位关系. 详细题解传送门 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=(a);i<=(b);++i) 4

hdu 5524 Subtrees dfs

Subtrees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description There is a complete binary tree with N nodes.The subtree of the node i has Ai nodes.How many distinct numbers are there of Ai? Input Th