puzzle(1331)活字飞花

目录

活字飞花

1,规则

2,通解公式

3,求通解的算法

4,使用方法

5,自动点击


活字飞花

最强大脑同款项目

1,规则

n*n(n>=6)的正方形格子,每次可以交换相邻2行,或者相邻2列,或者相邻2个十字,复原所有格子的位置。

考虑到边界情况,实际上相邻十字这个操作有3种情况:

2,通解公式

其实很容易就能找到,单独交换第0行第1个和第4个格子的方法。

只需要用上图中的红色十字(5v5)减去黄色十字(4v4)自然就能得到1v1单独交换的方法。

3,求通解的算法

数据结构:


int n;//行列数
struct changeOpt{
	int r1;
    int c1;
	int r2;
    int c2;
};

3个核心算法:


//opt的轴对称
changeOpt turn(changeOpt opt)
{
    return {opt.c1,opt.r1,opt.c2,opt.r2};
}
//算法的轴对称算法
vector<changeOpt> turn(vector<changeOpt>v)
{
    vector<changeOpt>ans;
    for(auto vi:v)ans.push_back(turn(vi));
    return ans;
}

//交换最后一行第1个和第4个格子
vector<changeOpt> alg1()
{
    vector<changeOpt>ans;
    ans.push_back({n-2,1,n-2,4});
    ans.push_back({n-2,1,n-1,1});
    ans.push_back({n-2,1,n-3,1});
    ans.push_back({n-1,1,n-1,4});
    ans.push_back({n-2,1,n-3,1});
    ans.push_back({n-2,1,n-1,1});
    return ans;
}
//交换第i行和第j行
vector<changeOpt> alg2(int i,int j)
{
    if(i>j)i^=j^=i^=j;
    vector<changeOpt>ans;
    for(int x=i;x<j;x++)ans.push_back({x,1,x+1,1});
    for(int x=j-1;x>i;x--)ans.push_back({x,1,x-1,1});
    return ans;
}

3个算法分别是轴对称算法、交换2个格子的算法、交换2行算法。

其中轴对称算法专门用来利用一个算法生成另外一个算法,所以可以称之为二阶算法,或者元算法。

利用3个核心算法即可层层递进,推导出另外6个算法:


//交换第i列和第j列
vector<changeOpt> alg3(int i,int j)
{
    return turn(alg2(i,j));
}

//交换第k行第1个和第4个格子
vector<changeOpt> alg4(int k)
{
    vector<changeOpt>ans=alg2(k,n-1);
    vector<changeOpt>ans2=alg1();
    for(auto v:ans2)ans.push_back(v);
    ans2=alg2(k,n-1);
    for(auto v:ans2)ans.push_back(v);
    return ans;
}

//交换第k行第i个和第j个格子
vector<changeOpt> alg5(int k,int i,int j)
{
    vector<changeOpt> ans;
    if(i==j)return ans;
    if(i>j)i^=j^=i^=j;
    if(j<2){
        vector<changeOpt>ans2=alg3(j,4);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg3(i,1);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg4(k);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg3(i,1);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg3(j,4);
        for(auto v:ans2)ans.push_back(v);
    }else{
        vector<changeOpt>ans2=alg3(i,1);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg3(j,4);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg4(k);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg3(j,4);
        for(auto v:ans2)ans.push_back(v);
        ans2=alg3(i,1);
        for(auto v:ans2)ans.push_back(v);
    }
    ret
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值