puzzle(0332)数字拼图旋转、九鼎之局、旋转数独

文章介绍了数字拼图游戏的三种模式:旋转、九鼎之局和轮换。在旋转模式中,提供了交换数字的17步公式;九鼎之局通过贪心策略和优化方法解决;轮换模式则分析了不同尺寸的解决方案,包括4x4和6x6的特殊情况。

目录

一,数字拼图——旋转

1,手动求解

2,计算机求解

二,九鼎之局

三,旋转数独

1,规则

2,解法

3,轮换对称性

4,求标准数独的9个九宫格的全排列空间的等价类个数

5,计算机求解

5.1 已有代码

5.2 修改字符串输入方式、判定是否有解

5.3 遍历9个九宫格的位置

5.4 枚举9个九宫格的每种位置是否数独有解

5.5 完整代码


一,数字拼图——旋转

数字华容道小游戏中的旋转模式

1,手动求解

很容易把第一行和第一列搞定,关键是右下角四个怎么排序。

出现这种情况,需要把5和6反过来。显然只要知道怎么交换5和6,就能轻松应付所有情况了。

经过几次尝试,我把公式找出来了,左上的旋转按钮是不需要的,所以我把其他三个按钮分别叫做上左右。

公式就是上上左上右上上右右左右右右左右右右,这17个操作下来,就把5和6对换了,其他的不动。

对于更高阶的情况,都可以直接化成3*3的情况,方法和数字拼图——滑动的方法一样。

2,计算机求解


void turn0(vector<int>&v)
{
    int x=v[0];
    v[0]=v[3],v[3]=v[4],v[4]=v[1],v[1]=x;
}
void turn1(vector<int>&v)
{
    int x=v[1];
    v[1]=v[4],v[4]=v[5],v[5]=v[2],v[2]=x;
}
void turn2(vector<int>&v)
{
    int x=v[3];
    v[3]=v[6],v[6]=v[7],v[7]=v[4],v[4]=x;
}
void turn3(vector<int>&v)
{
    int x=v[4];
    v[4]=v[7],v[7]=v[8],v[8]=v[5],v[5]=x;
}
void turn(int id,vector<int>&v)
{
    if(id==0)turn0(v);
    if(id==1)turn1(v);
    if(id==2)turn2(v);
    if(id==3)turn3(v);
}

vector<int> change56{1,1,2,1,3,1,1,3,3,2,3,3,3,2,3,3,3};

bool del3(vector<int>&v)
{
    if(v.size()<4)return false;
    for(int i=0;i+3<v.size();i++){
        if(v[i]==3 && v[i+1]==3 && v[i+2]==3 && v[i+3]==3){
            for(int j=i;j+4<v.size();j++)v[j]=v[j+4];
            v.resize(v.size()-4);
            return true;
        }
    }
    return false;
}

#define MOVE(id) opts.push_back(id),turn(id,v);
//输入123456789的排列,输出操作序列,0123分别是左上 右上 左下 右下
vector<int> solve33(vector<int>v)
{
    vector<int>opts;
    if(v[2]==1)MOVE(1);
    if(v[5]==1)MOVE(3);
    if(v[8]==1)MOVE(3);
    if(v[7]==1)MOVE(2);
    if(v[6]==1)MOVE(2);
    while(v[0]!=1)MOVE(0);
    if(v[6]==3)MOVE(2);
    if(v[3]==3)MOVE(2);
    if(v[8]==3)MOVE(3);
    if(v[7]==3)MOVE(3);
    while(v[1]!=3)MOVE(1);
    if(v[2]==2){
        MOVE(1);
        MOVE(1);
        MOVE(2);
        MOVE(2);
        MOVE(2);
        MOVE(1);
        MOVE(1);
        MOVE(2);
        MOVE(1);
    }else{
        if(v[6]==2)MOVE(2);
        if(v[3]==2)MOVE(2);
        while(v[4]!=2)MOVE(3);
        MOVE(1);
    }
    //至此是123******
    if(v[6]==4)MOVE(2);
    if(v[3]==4)MOVE(2);
    while(v[8]!=4)MOVE(3);
    if(v[5]==7){
        MOVE(3);
        MOVE(2);
        MOVE(3);
        MOVE(2);
    }else{
        while(v[3]!=7)MOVE(2);
        MOVE(3);
        MOVE(3);
        MOVE(2);
        MOVE(2);
        MOVE(2);
    }
    //至此是1234**7**
    while(v[4]!=5)MOVE(3);
    if(v[7]==6){
        MOVE(3);
        for(auto x:change56)MOVE(x);
    }
    if(v[8]==6){
        for(auto x:change56)MOVE(x);
        MOVE(3);
        MOVE(3);
        MOVE(3);
    }
    //至此是1234567**
    if(v[7]==9){
        MOVE(3);
        MOVE(3);
        for(auto x:change56)MOVE(x);
        MOVE(3);
        MOVE(3);
    }
    while(del3(opts));
    return opts;
}

二,九鼎之局

最强大脑同款项目。

就是数字拼图(旋转),使得每一行每一列都是9个不同的数字。

我的初始思路是贪心原则,一行行往下弄,最后只需要一个单独交换2个格子的公式即可。

但是也可能会变成这样:

右下角的9个无论怎么互换都不行了。

所以我的思路更新成,把右下角留出3个数,每个数3个。

即先按照贪心方法完成其他8个宫,最后一个宫是3个数各3个,就很容易完成,甚至不需要单独交换2格的公式。

  

最强大脑的同款项目中, 第一次达到榜一成就。

不过这个思路还是有一点偶然性,于是我把最强大脑选手的2个思路试了一下,即九宫格法和斜线法。

九宫格法:

斜线法:

这2个方法确实简单且高效,不会出现难搞的情况。 

三,旋转数独

最强大脑同款项目。

1,规则

使用四个旋转按钮和填充数字,使得变成一个完整的数独。

2,解法

(1)单个九宫格可以填充的数字就填充

这个case里面没有,那就跳过
(2)选择一个出现较多的数字,把它的9个位置都确定下来

这里的2就全部确定了
(3)选择一个数字较多的九宫格,确定和它在同一行的2个九宫格,把这3个九宫格都移到第一行

这里第一行的3个九宫格就确定在同一行了
(4)剩下的6个九宫格里面,再选择一个数字较多的

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值