• hdu 4090--GemAnd Prince(搜索)


    题目链接

    Problem Description
    Nowadays princess Claire wants one more guard and posts the ads throughout the kingdom. For her unparalleled beauty, generality, goodness and other virtues, many people gather at the capital and apply for the position. Because princess Claire is very clever, she doesn't want a fool to be her guard. As Claire is clever, she invents a game to test the applicants. The game is described as follows.
    The game begins with a rectangular board of n rows and m columns, containing n*m grids. Each grid is filled with a gem and each gem is covered by one color, denoted by a number.(as the following shows).





    If a gem has the same color with another one, and shares the same corner or the same border with it, the two are considered to be adjacent. Two adjacent gems are said to be connective. And we define that if A and B are connective, B and C are connective, then A and C are connective, namely the adjacency is transitive. Each time we can choose a gem and pick up all of the gems connected to it, including itself, and get a score equal to the square of the number of the gems we pick this time(but to make the game more challenging, the number of gems to be picked each time must be equal or larger than three).Another rule is that if one gem is picked, all the gems above it(if there is any)fall down to fill its grid,and if there is one column containing no gems at all, all the columns at its right(also if there is any) move left to fill the column. These rules can be shown as follows.


    As the picture [a] above,all the gems that has color 1 are connective. After we choose one of them to be picked, all the gems that are connected to it must also be picked together, as the picture [b] shows (here we use 0 to denote the holes generated by the absence of gems).
    Then the rest gems fall, as shown in picture [c]. Then the rest gems move left, as shown in picture [d]. Because we picked six gems at this time, our score increases 6*6=36.And furthermore, because we cannot find another gem, which has at least three gems connected to it(including itself),to be picked, the game comes to an end.
    Each applicant will face such a board and the one who gets the highest score will have the honor to serve princess Claire. 
    Aswmtjdsj also wants to serve for princess Claire. But he realizes that competing with so many people, even among whom there are powerful ACMers, apparently there is little chance to succeed. With the strong desire to be the lucky dog, Aswmtjdsj asks you for help. Can you help make his dream come true?
     
    Input
    There are no more than 15 test cases, separated by a blank line, end with EOF. Each case has n+1 lines, the first line of a case has three integers n, m, k (1<=n, m<=8, 1<=k<=6). Each of the next n lines contains m integers. The integer at (i+1)th line and jth column denotes the color of the gem at the grid (i, j), where the grid(1, 1) denotes the top left one, while the grid(n, m) is the lower right one. The integer in the grid is among [1, k].
     
    Output
    For each case you should output the highest score you can get in one single line.
     
    Sample Input
    3 3 3
    1 1 3
    1 2 1
    1 1 2
     
    5 4 3
    2 2 3 3
    1 1 3 3
    3 2 2 2
    3 1 1 1
    3 1 2 2
     
    Sample Output
    36
    103
     
    题意:有一个n*m的格状棋盘,每个小格上有一个数字,现在有一个游戏规则:取棋盘上的一个方格,与方格相连的且数值相同的方格也会被选取,每次选取小方格获得的分数为获得的方格数的平方值(方格数>=3才能被选取,小于3不能选取该方格),取走方格后,上面的方格都会向下落填补空的方格,然后如果某一列全空,那么右边的方格会左移补充,游戏直至找不到相连的3个以上的方格为止。现在求能获得的最大得分?
     
    思路:搜索,注意剪枝,当前已经获得的分数与剩下的方格能获得的最大得分之和小于ans,则return。
     
    代码如下:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    //#include <windows.h>
    using namespace std;
    struct Node
    {
        int a[9][9];
    };
    int n,m,k;
    int dx[8]={1,1,1,0,0,-1,-1,-1};
    int dy[8]={1,0,-1,1,-1,1,0,-1};
    int ans;
    
    /**void print(Node s)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                cout<<s.a[i][j]<<" ";
            cout<<endl;
        }
    }*/
    int get(Node s)
    {
        int r[10];
        for(int i=1;i<=k;i++) r[i]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                r[s.a[i][j]]++;
        }
        int ans=0;
        for(int i=1;i<=k;i++) ans+=r[i]*r[i];
        return ans;
    }
    int dfs(Node &t,int x,int y,int d,Node &p)
    {
        int num=1;
        t.a[x][y]=0;
        p.a[x][y]=0;
        for(int i=0;i<8;i++)
        {
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(nx<1||nx>n||ny<1||ny>m||t.a[nx][ny]!=d) continue;
            num+=dfs(t,nx,ny,d,p);
        }
        return num;
    }
    void change1(Node &t)
    {
        for(int i=1;i<=m;i++)
        {
            int pos=n;
            for(int j=n;j>=1;j--)
            {
                if(t.a[j][i]==0) continue;
                t.a[pos][i]=t.a[j][i];
                if(pos!=j) t.a[j][i]=0;
                pos--;
            }
        }
    }
    void change2(Node &t)
    {
        int pos=1;
        for(int i=1;i<=m;i++)
        {
            int f=0;
            for(int j=1;j<=n;j++)
              if(t.a[j][i]!=0) { f=1; break; }
            if(f)
            {
                for(int j=1;j<=n;j++)
                {
                    t.a[j][pos]=t.a[j][i];
                    if(pos!=i) t.a[j][i]=0;
                }
                pos++;
            }
        }
    }
    void solve(Node &s,int sum)
    {
        if(sum+get(s)<=ans) return ;
        Node t=s;
        Node p=s;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(t.a[i][j]==0||p.a[i][j]==0) continue;
                int tmp=dfs(t,i,j,t.a[i][j],p);
                if(tmp>=3)
                {
                    change1(t);
                    change2(t);
                    //Sleep(12000);
                    ans=max(ans,sum+tmp*tmp);
                    solve(t,sum+tmp*tmp);
                }
                t=s;
            }
        }
    }
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            Node s;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                   scanf("%d",&s.a[i][j]);
            ans=0;
            solve(s,0);
            printf("%d
    ",ans);
        }
        return 0;
    }
    /**
    3 3 5
    0 0 3
    0 2 0
    0 0 2
    */
  • 相关阅读:
    【转】人类的心理行为模式----《影响力》笔记
    c++类型形参的实参的受限转换
    如何确定网页和查询的相关性
    英语美文摘要
    特殊的字符数组
    c++中的虚函数
    [C#] 常用工具类——应用程序属性信息访问类
    c#常用工具类:文件和二进制转换
    [C#] 常用工具类——文件操作类
    Lamda和Linq语法对比详细
  • 原文地址:https://www.cnblogs.com/chen9510/p/7622739.html
Copyright © 2020-2023  润新知