飞行员兄弟(二进制枚举, 详解)

思路:将4*4矩阵每一个位置看成一个状态,总共有2^16次方种状态,暴力枚举每种状态即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define f first
#define s second
using namespace std;
typedef pair<int, int> PII;
const int N=10;
int get(int x, int y);//得到二进制数中对应位置
void turn_all(int x, int y);//改变行列
void turn_one(int x, int y);//改变单一点

vector<PII> res;
char g[N][N], backups[N][N];//原数组, 备份数组

signed main()
{
    for(int i=0;i<4;i++) scanf("%s", g[i]);
    
    for(int op=0;op<(1<<16);op++)//枚举所有操作状态方案
    {
        memcpy(backups, g, sizeof g);
        vector<PII> temp;
        
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
                if(op>>get(i, j)&1)//若是1, 则操作
                {
                    turn_all(i, j);
                    temp.push_back({i, j});
                }
                    
        bool dark=false;//判断有无+
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
                if(g[i][j]=='+')
                {
                    dark=true;
                    break;
                }
        //如果答案数组是空或者答案数组操作数大于当前数组,更新答案        
        if(!dark&&(res.empty()||res.size()>temp.size())) res=temp;
        
        memcpy(g, backups, sizeof backups);
    }
    
    cout<<res.size()<<endl;
    for(auto it:res) printf("%d %d\n", it.f+1, it.s+1);
}

void turn_all(int x, int y)
{
    for(int i=0;i<4;i++)
    {
        turn_one(x, i);
        turn_one(i, y);
    }
    
    turn_one(x, y);
}

void turn_one(int x, int y)
{
    g[x][y]=='+'?g[x][y]='-':g[x][y]='+';
}

int get(int x, int y)
{
    return 4*x+y;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值