HDU-2259-Continuous Same Game (2)(BFS+DFS+模拟)

Problem Description

After repeated attempts, LL finds the greedy strategy is very awful in practice. Even there is no apparent evidence to proof it is better than a random one. So he has to drop this strategy and try to discover a better one.

Input

There are 100 test cases. Each test case begins with two integers n,m ( 5<=n,m<=20 ), which is the size of the board. Then n lines follow, each contains m characters, indicating the color of the block. There are 5 colors, and each with equal probability.

Output

For each test case, first output a single line containing the number of steps S. Then S lines follow, each contains two integers indicating the position of an arbitrary block of the group you want to remove.

For the i-th test case, let Ai is the total point of your scheme and Bi is the total point of the greedy strategy . Then I will calculate the average of (Ai/Bi), 1<=i<=100. You will get WA if your ouput is invalid or this average is less than 1.5.

Sample Input

5 5
35552
31154
33222
21134
12314

Sample Output

5
2 2
0 0
1 1
2 1
4 4

Hint

35552    35000    00000    00000    00000    00000
31154    31552    05552    00002    00002    00000
33222    33154    01154    01104    00004    00000
21134    21134    21134    21134    20034    20030
12314    12314    12314    12314    12314    12312

The total point is 6+12+12+12+6=48.

思路:总体是用BFS搞的,消除格子的时候就用DFS。对每一个状态都求一个评估值val,用优先队列来维护,每次使评估值最大的元素出队,并且更新答案。题目不要求最优解,处理25次左右就可以满足题意了。

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

struct S{
char mp[20][21];
int step,ans,x[50],y[50],val;
int num[20][20];

bool operator<(const S &p) const
{
    return val<p.val;
}

}t,ans,tt;

int n,m,nxt[4][2]={{1,0},{0,1},{-1,0},{0,-1}},cnt;
char temp[20][21];
bool vis[20][20];

void dfs(int x,int y,char c)
{
    int i,j;

    for(i=0;i<4;i++)
    {
        x+=nxt[i][0];
        y+=nxt[i][1];

        if(x>=0 && x<n && y>=0 && y<m && !vis[x][y] && temp[x][y]==c)
        {
            vis[x][y]=1;

            cnt++;

            dfs(x,y,c);
        }

        x-=nxt[i][0];
        y-=nxt[i][1];
    }
}

void tran(int x,int y,char num,char (*d)[21])
{
    for(int i=0;i<4;i++)
    {
        x+=nxt[i][0];
        y+=nxt[i][1];

        if(x>=0 && x<n && y>=0 && y<m && d[x][y]==num)
        {
            d[x][y]='0';

            tran(x,y,num,d);
        }

        x-=nxt[i][0];
        y-=nxt[i][1];
    }
}

void move(char (*d)[21])
{
    int i,j,k;

    for(i=n-1;i>=0;i--)//向下移动
    {
        for(j=0;j<m;j++)
        {
            if(d[i][j]=='0')
            {
                for(k=i-1;k>=0;k--)
                {
                    if(d[k][j]>'0')
                    {
                        d[i][j]=d[k][j];
                        d[k][j]='0';

                        break;
                    }
                }
            }
        }
    }

    int t=m-1;
    while(t--)//向左移动,注意连续两列都为空的情况
    {
        for(j=0;j<m-1;j++)
        {
            for(i=0;i<n;i++) if(d[i][j]>'0') break;

            if(i==n)
            {
                for(i=0;i<n;i++)
                {
                    d[i][j]=d[i][j+1];

                    d[i][j+1]='0';
                }
            }
        }
    }
}

void eval(S &node)//评估
{
    int i,j;

    for(i=0;i<n;i++) for(j=0;j<m;j++) vis[i][j]=0,temp[i][j]=node.mp[i][j];

    node.val=node.ans;

    for(i=0;i<n;i++) for(j=0;j<m;j++)
    {
        node.num[i][j]=0;

        if(temp[i][j]>'0' && !vis[i][j])
        {
            vis[i][j]=1;

            cnt=1;

            dfs(i,j,temp[i][j]);

            if(cnt>1)
            {
                node.num[i][j]=cnt;

                node.val+=cnt*(cnt-1);
            }
        }
    }
}

int main()
{
    int i,j,p,q,tot;

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

        t.step=0;
        t.ans=0;
        t.val=0;

        ans.ans=0;

        priority_queue<S>que;

        eval(t);

        que.push(t);

        tot=0;

        while(!que.empty())
        {
            t=que.top();

            if(t.ans>ans.ans) ans=t;//更新答案

            tot++;

            if(tot>24) break;//循环25次就退出

            que.pop();

            for(i=0;i<n;i++) for(j=0;j<m;j++)
            {
                if(t.num[i][j])
                {
                    tt=t;

                    tran(i,j,t.mp[i][j],t.mp);//清除格子

                    t.mp[i][j]='0';

                    move(t.mp);//移动格子

                    t.x[t.step]=i;
                    t.y[t.step]=j;
                    t.step++;
                    t.ans+=t.num[i][j]*(t.num[i][j]-1);

                    eval(t);//重新评估

                    que.push(t);

                    t=tt;
                }
            }
        }

        printf("%d\n",ans.step);

        for(i=0;i<ans.step;i++) printf("%d %d\n",ans.x[i],ans.y[i]);
    }
}
时间: 2024-08-29 20:55:08

HDU-2259-Continuous Same Game (2)(BFS+DFS+模拟)的相关文章

HDU ACM 1044 Collect More Jewels BFS+DFS

题意:在一个迷宫中,有一些宝物,从起点走到终点,问在给定的时间内,到达终点后所能拾取珠宝的最大价值. 分析(BFS+DFS): 1.求入口到第一个取宝物的地方的最短距离 2.求第i个取宝物的地方到第i+1个取宝物的地方的最短距离 3.求第n个取宝物的地方到出口的最短距离 4.保证以上3点能在时间L内实现的情况下,取得的宝石价值最大. BFS特点:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元来存储状态) DFS特点:对于解决遍历和求所有问题有效,对于问

HDU 1044 Collect More Jewels【BFS+DFS+建立距离图】

Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6707    Accepted Submission(s): 1556 Problem Description It is written in the Book of The Lady: After the Creation, the cruel

HDU 4771 Stealing Harry Potter&#39;s Precious dfs+bfs

Stealing Harry Potter's Precious Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his

hdu 4771 Stealing Harry Potter&#39;s Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: 目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离: 解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点  j 的距离: 然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的: AC代码: 1 #include<iostream>

HDU 1254 (经典游戏)推箱子 BFS+dfs

Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动. 现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格. Input 输入数据的第一行是一个整数T(1<=T<=20),代表测试

HDU 4771 Stealing Harry Potter&#39;s Precious(BFS + DFS)

HDU 4771 Stealing Harry Potter's Precious 题目链接 题意:给定人的起始位置和k个宝物,求人拿完全部宝物最小的步数 思路:先bfs打出两两之间路径,然后dfs暴力求答案,因为宝物才4个,所以暴力是没问题的 代码: #include <stdio.h> #include <string.h> #include <queue> #include <algorithm> using namespace std; const

PKU 1562/HDU 1241 Oil Deposits(原油有多少块区域---BFS,DFS)

Oil Deposits Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region o

ZOJ 3048 (HDU 2258) Continuous Same Game (1)

Problem Description Continuous Same Game is a simple game played on a grid of colored blocks. Groups of two or more connected (orthogonally, not diagonally) blocks that are the same color may be removed from the board. When a group of blocks is remov

邻结矩阵的建立和 BFS,DFS;;

邻结矩阵比较简单,, 它的BFS,DFS, 两种遍历也比较简单,一个用队列, 一个用数组即可!!!但是邻接矩阵极其浪费空间,尤其是当它是一个稀疏矩阵的时候!!!---------------------------------------------------------------------------------------------------------------------------------------//邻接矩阵的建立和 其BFS, DFS, 遍历 #include <