第三届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;

}

  

 

你可能感兴趣的:(number)