zoukankan      html  css  js  c++  java
  • Hdu OJ 5113 Black And White (2014ACM/ICPC亚洲区北京站) (搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5113

    题目大意:有k种颜色的方块,每种颜色有ai个, 现在有n*m的矩阵, 问这k种颜色的方块能否使任意两个相连的方块颜色不一样填满整个矩阵,如果可以输出任意一种。

    解题思路:由于n,m在[1, 5]内, 所以直接暴力枚举; 需要注意的是:需要剪枝一下。

    代码如下:

    #include<stdio.h>
    #include<string.h>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N = 103;
    int n, m, k;
    int a[N], mp[N][N];
    bool is;
    bool judge(int x, int y, int s)
    {
        bool p = true, q = true;
        if(x - 1 >= 1 && mp[x-1][y] == s)
            p = false;
        if(y - 1 >= 1 && mp[x][y-1] == s)
            q = false;
        return p && q;
    }
    
    void dfs(int x, int y, int cou)
    {
        int sum = 0, mx = 0;
        for(int i=1; i<=k; ++ i)
        {
            sum += a[i];
            if(a[i] > mx)
                mx = a[i];
        }
        if(sum - mx < mx - 1)
            return;
        if(cou == n*m)
        {
            is = true;
            return ;
        }
    
        for(int i=1; i<=k; ++ i)
        {
            if(a[i] && judge(x, y, i))
            {
                a[i] --;
                mp[x][y] = i;
                if(y == m)
                    dfs(x+1, 1, cou + 1);
                else
                    dfs(x, y+1, cou + 1);
                if(is)
                    return ;
                a[i] ++;
            }
        }
    }
    
    void solve(int cases)
    {
        scanf("%d%d%d", &n, &m, &k);
        int sum = 0, mx = 0;
        for(int i=1; i<=k; ++ i)
        {
            scanf("%d", &a[i]);
            sum += a[i];
            if(a[i] > mx)
                mx = a[i];
        }
        printf("Case #%d:
    ", cases);
        if(sum - mx < mx - 1)
            printf("NO
    ");
        else
        {
            printf("YES
    ");
            memset(mp, -1, sizeof(mp));
            is = false;
            dfs(1, 1, 0);
            for(int i=1; i<=n; ++ i)
                for(int j=1; j<=m; ++ j)
                    printf(j == m? "%d
    " : "%d ", mp[i][j]);
        }
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for(int i = 1; i <= t; ++ i)
        {
            solve(i);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    P1030 求先序排列 P1305 新二叉树
    spfa
    Clairewd’s message ekmp
    Cyclic Nacklace hdu3746 kmp 最小循环节
    P1233 木棍加工 dp LIS
    P1052 过河 线性dp 路径压缩
    Best Reward 拓展kmp
    Period kmp
    Substrings kmp
    Count the string kmp
  • 原文地址:https://www.cnblogs.com/aiterator/p/5897232.html
Copyright © 2011-2022 走看看