poj2965

#include <iostream>
#include <stdio.h>

using namespace std;

struct game
{
    char p[4][4];
    char f[4][4];
    int n,i,j,up;
};
game dl[100000],a;

char fan(char kaig)
{
    if (kaig=='-') return '+';else return '-';
}

game flip(game b,int i,int j)
{
    int k;
    for (k=0;k<=3;k++) b.p[i][k]=fan(b.p[i][k]);
    for (k=0;k<=3;k++) b.p[k][j]=fan(b.p[k][j]);
    b.p[i][j]=fan(b.p[i][j]);
    b.i=i;b.j=j;
    int m,n;
    for (m=0;m<=i-1;m++)                           //按一定顺序翻 翻过位置做标记
        for (n=0;n<=3;n++) b.f[m][n]='1';
    for (n=0;n<=j;n++) b.f[i][n]='1';
    return b;
}

bool judge(game a)
{
    int i,j;
    for (i=0;i<=3;i++)
        for (j=0;j<=3;j++)
             if (a.p[i][j]!='-') return 0;
    return 1;
}
int main()
{
    int i,j,c1,c2;
    //freopen("in.txt","r",stdin);
    for (i=0;i<=3;i++)
    {
       scanf("%s",a.p[i]);
       
    }
    for (i=0;i<=3;i++)
        for (j=0;j<=3;j++) a.f[i][j]='0';
    c1=1;c2=1;
    dl[1]=a;a.n=0;a.up=0;
    if(judge(a)){
        printf("0\n");
        return 0;
    }
    while (c1<=c2)
    {
        for (i=0;i<=3;i++)
           for (j=0;j<=3;j++)
                if (dl[c1].f[i][j]=='0')
                {
                   c2++;
                   dl[c2]=flip(dl[c1],i,j);
                   dl[c2].up=c1;
                   dl[c2].n=(dl[c1].n)+1;
                   if (judge(dl[c2]))
                   {
                       game d;
                       printf("%d\n",dl[c2].n);
                       d=dl[c2];
                       while (d.n!=0)
                       {
                          printf("%d %d\n",d.i+1,d.j+1);
                          d=dl[d.up];
                       }
                       break;
                   }
                }
       c1++;
    }
    return 0;
}
题目大意:一个冰箱有16个开关,呈方形分布(4*4矩阵),“+”表示关闭,“-”表示开着,当所有的开关为“+”时冰箱才能打开。当去翻转一个开关时,在该开关所在列和行的所有开关都要翻转,即开变关,关变开。问至少需要多少次才能打开冰箱。
BFS 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值