poj 1753 Flip Game

本文通过一个具体的实例展示了状态压缩宽度优先搜索(BFS)算法的应用过程。该实例涉及在一个4x4的棋盘上进行操作,目标是将所有格子的状态统一为单一颜色,同时记录最少的操作次数。文章提供了完整的源代码,并详细解释了如何使用状态压缩来减少搜索空间,最终高效地解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

跟着叉姐的步伐走的。。。他说这是枚举题,于是我真的暴力了,什么搜索,二进制都没用,以后有能力补上吧。。。。(前面八月写的)老子现在会了 第二个代码状压BFS

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<map>
int x[5]={0,0,0,1,-1},y[5]={0,1,-1,0,0},sum1,sum2,cishu,i,j,k,cishu1;
int b[4][4];
char a[4][5],c[4][5];
int main()
{
 {
        cishu=10000000;
   for(i=0;i<4;i++)
     scanf("%s",c[i]);
   for(b[0][0]=0;b[0][0]<=1;b[0][0]++)
     for(b[0][1]=0;b[0][1]<=1;b[0][1]++)
       for(b[0][2]=0;b[0][2]<=1;b[0][2]++)
           for(b[0][3]=0;b[0][3]<=1;b[0][3]++)
              for(b[1][0]=0;b[1][0]<=1;b[1][0]++)
                 for(b[1][1]=0;b[1][1]<=1;b[1][1]++)
                     for(b[1][2]=0;b[1][2]<=1;b[1][2]++)
                         for(b[1][3]=0;b[1][3]<=1;b[1][3]++)
                           for(b[2][0]=0;b[2][0]<=1;b[2][0]++)
                              for(b[2][1]=0;b[2][1]<=1;b[2][1]++)
                                 for(b[2][2]=0;b[2][2]<=1;b[2][2]++)
                                     for(b[2][3]=0;b[2][3]<=1;b[2][3]++)
                                       for(b[3][0]=0;b[3][0]<=1;b[3][0]++)
                                         for(b[3][1]=0;b[3][1]<=1;b[3][1]++)
                                           for(b[3][2]=0;b[3][2]<=1;b[3][2]++)
                                              for(b[3][3]=0;b[3][3]<=1;b[3][3]++)
                                              {
                                                for(i=0;i<4;i++)
                                                  strcpy(a[i],c[i]);
                                                sum1=0;sum2=0;cishu1=0;
                                                 for(i=0;i<4;i++)
                                                    for(j=0;j<4;j++)
                                                    {
                                                        if(b[i][j]==1)
                                                        {
                                                          cishu1++;
                                                          for(k=0;k<5;k++)
                                                           {
                                                              if(((i+x[k])>=0&&(i+x[k])<=3)&&((j+y[k])>=0&&(j+y[k])<=3))
                                                                {
                                                                  if(a[i+x[k]][j+y[k]]=='w')a[i+x[k]][j+y[k]]='b';
                                                                  else  a[i+x[k]][j+y[k]]='w';
                                                                }   
                                                           }
                                                        }
                                                      }
                                                  for(i=0;i<4;i++)
                                                    for(j=0;j<4;j++)
                                                    {
                                                      if(a[i][j]=='w')sum1++;
                                                      else sum2++;
                                                      }
                                                if((sum1==16||sum2==16)&&cishu1<cishu)cishu=cishu1;
                                              }
         if(cishu!=10000000) printf("%d\n",cishu);
         else printf("Impossible\n");
    }
    return 0;                                         
}

BFS

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
int all=0,i,j,k,z=0;
char mp[4][5];
using namespace std;
int bu[5][2]={0,1,0,-1,1,0,-1,0,0,0},result;
bool sym=false,Sym[200000]={false};
struct chess{
   int t,s;
}node1,node2;
int main()
{

    for(i=0;i<4;i++)
    scanf("%s",mp[i]);
    for(i=0;i<16;i++)
      all|=(1<<i);
    z=0;
    for(i=0;i<4;i++)
    for(j=0;j<4;j++)
    if(mp[i][j]=='b')z|=(1<<(i*4+j));
    queue<chess>node;
    node1.s=z;
    node1.t=0;
    node.push(node1);
    while(!node.empty())
    {
      node1 = node.front();
      node.pop();
      if(node1.s==all||node1.s==0){result=node1.t;sym=true;break;}
      for(i=0;i<4;i++)
        for(j=0;j<4;j++)
       {
          int w=node1.s;
          for(k=0;k<5;k++)
          {
              int x=i+bu[k][0],y=j+bu[k][1];
              if(x>=0&&x<4&&y>=0&&y<4)
              {
                  if((w&(1<<(x*4+y)))!=0)
                   w^=(1<<(x*4+y));
                  else
                   w|=(1<<(x*4+y));
              }
          }
          if(Sym[w]==false)
          {
              Sym[w]=true;
              node2.s=w;
              node2.t=node1.t+1;
              node.push(node2);
          }
      }
    }
    if(sym==false)printf("Impossible\n");
    else printf("%d\n",result);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值