BNUOJ 4304 硬币迷阵

Prayer是一位著名的考古学家,某次他在埃及考察时发现了一个古埃及硬币迷阵,这种古埃及硬币有两面,正面为阿努比斯的头像,反面则为金字塔图像

BNUOJ 4304 硬币迷阵_第1张图片 BNUOJ 4304 硬币迷阵_第2张图片
这个迷阵由12个古埃及硬币构成,形状如下图:
BNUOJ 4304 硬币迷阵_第3张图片
当我们把所有的硬币全都翻成正面或全都翻成反面时,我们就可以成功解开这个迷阵。但是这个迷阵有一个小机关:当我们翻动某一个硬币的时候,与它同行或同列的硬币也将同时被翻动。例如当我们翻动上图箭头所指的硬币之后,迷阵的情况会变成下图所示
BNUOJ 4304 硬币迷阵_第4张图片
现在Prayer希望知道他最少需要翻动几次硬币才能解开这个迷阵

Input

第一行是一个整数T表示数据组数。每组输入由4行构成,对应迷阵4行的情况,0表示正面,1表示反面。每组输入之后有一个空行。

Output

对于每组输入,输出5行,一个行只有一个数表示所需的最少步数,接下来的四行对应迷阵的四行,表示最少步数对应的解决方案,0表示不翻动这个硬币,1表示翻动这个硬币。如果有多个方案能够达到最少步数,输出”123.cpp”。输出时注意不要有多余的空格。

Sample Input

4
  0 0
0 0 0 0
0 0 0 0
  0 0

  0 0
1 0 1 1
1 0 1 1
  0 1

  0 0
1 1 0 1
0 1 0 0
  0 0

  1 1
1 1 0 1
0 0 1 0
  0 0

Sample Output

0
  0 0
0 0 0 0
0 0 0 0
  0 0
1
  1 0
0 0 0 0
0 0 0 0
  0 0
4
  0 0
1 0 1 1
0 0 1 0
  0 0
6
123.cpp

Source

2010年北京师范大学新生程序设计竞赛正式赛

Author

temperlsyer 
这题主要要有回溯思想
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t;
int a[10][10];
int b[10][10];
int c[10][10];
int d;
int s;
int ma;
int cpp;
int on()
{
    for(int i=1; i<=4; i++)
    {
        for(int j=1; j<=4; j++)
        {
            if(a[i][j]==-1)return 0;
        }
    }
    return 1;
}
int back()
{
    for(int i=1; i<=4; i++)
    {
        for(int j=1; j<=4; j++)
        {
            if(a[i][j]==1)return 0;
        }
    }
    return 1;
}
void solve(int u)
{
    if(u==15)
    {
        if(on()||back())
        {
            if(s<ma)
            {
                cpp=0;
                ma=s;
                for(int i=1; i<=4; i++)
                {
                    for(int j=1; j<=4; j++)
                    {
                        c[i][j]=b[i][j];
                        //cout<<b[i][j]<<" ";
                    }
                    //cout<<endl;
                }
            }
            else if(s==ma)cpp=1;
        }
        return;
    }
    int x=u/4+1;
    int y=u%4+1;
    if(a[x][y]!=0)
    {
        solve(u+1);
        s++;
        a[x][y]=-a[x][y];
        for(int i=1; i<=4; i++)
        {
            a[i][y]=-a[i][y];
            a[x][i]=-a[x][i];
        }
        b[x][y]=1;
        solve(u+1);
        s--;
        a[x][y]=-a[x][y];
        for(int i=1; i<=4; i++)
        {
            a[i][y]=-a[i][y];
            a[x][i]=-a[x][i];
        }
        b[x][y]=0;
    }
    else solve(u+1);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        for(int i=2; i<=3; i++)
        {
            scanf("%d",&d);
            if(d==0)a[1][i]=-1;
            else a[1][i]=1;
        }
        for(int i=2; i<=3; i++)
        {
            for(int j=1; j<=4; j++)
            {
                scanf("%d",&d);
                if(d==0)a[i][j]=-1;
                else a[i][j]=1;
            }
        }
        for(int i=2; i<=3; i++)
        {
            scanf("%d",&d);
            if(d==0)a[4][i]=-1;
            else a[4][i]=1;
        }
        s=0;
        ma=20;
        cpp=0;
        if(!on()&&!back())solve(0);
        else ma=0;
        if(cpp==1)cout<<ma<<endl<<"123.cpp"<<endl;
        else
        {
            cout<<ma<<endl;
            cout<<"  "<<c[1][2]<<" "<<c[1][3]<<endl;
            for(int i=2; i<=3; i++)
            {
                for(int j=1; j<4; j++)cout<<c[i][j]<<" ";
                cout<<c[i][4]<<endl;
            }
            cout<<"  "<<c[4][2]<<" "<<c[4][3]<<endl;
        }
    }
    return 0;
}


你可能感兴趣的:(BNUOJ 4304 硬币迷阵)