POJ-1753(递归枚举)

该博客讨论了如何解决一个4x4棋盘翻转棋子的问题,目标是通过最少的步数使所有棋子变为同色。博主首先检查棋盘是否初始为纯色,若是则直接输出答案0。接着,博主尝试从翻转1到16个棋子,用递归枚举所有可能的翻转组合。如果在翻转过程中达到纯色状态,则输出步数;若翻转16个棋子仍无法达成,则输出'Impossible'。文章附有相关代码实现。

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

题目链接:http://poj.org/problem?id=1753

题目大意:有4*4的正方形棋盘,里面有黑白棋子,我们翻转一个棋子会改变它本身以及周围棋子的颜色,求最少多少步可以把所以棋子翻成同色。

思路:首先判断棋盘本身是否为纯色,如果是输出0。

         从挑出1个棋子翻转开始,挑出2个翻转,3个,4个……16个,共有2的16次方种翻转方法。

         在翻转过程中若已经达成纯色则跳出循环输出答案。

         若翻转16个棋子还是没有变成纯色则输出impossible。

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
int panduan(int bitss[])
{
    for(int i=0;i<15;i++)
    {
        if(bitss[i]!=bitss[i+1])
            return 0;
    }
    return 1;
}
void fanzhuan(int num2[],int t)
{
    num2[t]=-num2[t];
    if(t-4>=1) num2[t-4]=-num2[t-4];
    if(t+4<=16) num2[t+4]=-num2[t+4];
    if(t+1<=16) num2[t+1]=-num2[t+1];
    if(t-1>=1) num2[t-1]=-num2[t-1];
}
void combine(int* arr, int len, int* result, int count, const int NUM, int* last)
{
  int i;
  for (i=len;i>=count;i--)
  {
    result[count-1]=i-1;
    if (count>1)
    {combine(arr, i - 1, result, count - 1, NUM, last);}
    else
    {
      int j = 0;
      int new_arr[20];
      for (j = 0; j < 16; j++)
      {
        new_arr[j] = arr[j];
      }
      for (j = NUM - 1; j >=0; j--)
      {
         fanzhuan(new_arr,result[j]);
      }
      if (panduan(new_arr)==1)
      {
         *last = NUM;
         break;
      }
    }
  }
}

int main()
{
    int bits[20];
    int m=15;
    char str[5];
    for(int i=1;i<=4;i++)
    {
        scanf("%s",str);
        for(int j=0;j<4;j++)
        {
            if(str[j]=='b') {bits[m]=1;m--;}
            else {bits[m]=-1;m--;}
        }
    }
    if (panduan(bits)==1) cout<<"0"<<endl;
    else
    {
        int new_bits[20];
        for (int i=0;i<16;i++)
        {
            new_bits[i] = bits[i];
        }
        int j;
        int last = 0;
        for (j = 1; j <= 16; j++)
        {
            int* result = (int*)malloc(sizeof(int)*j);
            combine(new_bits,16,result,j,j,&last);
            if (last == j)
            {
                printf("%d\n", last);
                break;
            }
            for (int i=0;i<16;i++)
            {
                new_bits[i] = bits[i];
            }
        }
        if (j == 17)
        {
            printf("Impossible\n");
        }
    }
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值