第三届ACM山东省赛D题_Mine Number_枚举

枚举第一行即可,与训练指南上例题相似

代码如下:

#include <cstdio>
#include <cstring>
int a[21][21],b[21][21],n,m;
char s[25][25];
bool check_line(int x)
{
    int ans=b[0][x];
    if (x)
        ans+=b[0][x-1];
    if (x<m-1)
        ans+=b[0][x+1];
    if (ans==a[0][x] || ans+1==a[0][x])
        return true;
    return false;
}
int g(int x,int y)
{
    int ans=b[x][y];
    if (x)
        ans+=b[x-1][y];
    if (y)
        ans+=b[x][y-1];
    if (y<m-1)
        ans+=b[x][y+1];
    return ans;
}
bool f(int s)
{
    for (int i=0; i<m; ++i)
        if (s & (1<<i))
            b[0][i]=1;
        else
            b[0][i]=0;
    if (n==1)
    {
        for (int i=0; i<m; ++i)
            if (g(0,i)!=a[0][i])
                return false;
        return true;
    }
    int i,j;
    for (i=0; i<m; ++i)
        if (!check_line(i))
            return false;
    for (i=1; i<n; ++i)
        for (j=0; j<m; ++j)
            if (g(i-1,j)==a[i-1][j])
                b[i][j]=0;
            else if (g(i-1,j)+1==a[i-1][j])
                b[i][j]=1;
            else
                return false;
    for (i=0; i<m; ++i)
        if (g(n-1,i)!=a[n-1][i])
            return false;
    return true;
}
int main()
{
    int i,j,T,kcase=0;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&m);
        getchar();
        for (i=0; i<n; ++i)
            scanf("%s",s[i]);
        for (i=0; i<n; ++i)
            for (j=0; j<m; ++j)
                a[i][j]=s[i][j]-'0';
        for (int s=0; s<(1<<m); ++s)
            if (f(s))
                break;
        printf("Case %d:\n",++kcase);
        for (i=0; i<n; ++i)
        {
            for (j=0; j<m; ++j)
                if (b[i][j])
                    printf("*");
                else
                    printf(".");
            printf("\n");
        }
    }
    return 0;
}

  

 

posted @ 2013-06-06 12:52  Chierush  阅读(218)  评论(0)    收藏  举报