AcWing 116. 飞行员兄弟 解题思路及代码

本文描述了解决一个编程问题的方法,通过四重循环暴力枚举二进制操作来求解飞行员兄弟问题,作者提到虽然没有递推的规律,但整体思维量较小。
摘要由CSDN通过智能技术生成

先贴个题目:

以及原题链接: 116. 飞行员兄弟 - AcWing题库icon-default.png?t=N7T8https://www.acwing.com/problem/content/118/

然后是我的代码:

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
struct zuobiao
{
    int x;
    int y;
};
zuobiao list[1000], result[1000];
int s = 0, Min = 10000;
char map[4][4], backup[4][4];
void press(int x, int y)
{
    for (int i = 0; i < 4; ++i)
    {
        if (map[x][i] == '-')
            map[x][i] = '+';
        else
            map[x][i] = '-';
        if (map[i][y] == '-' && i != x)
            map[i][y] = '+';
        else if(i!=x)
            map[i][y] = '-';
    }
    list[s].x = x+1;
    list[s].y = y+1;
    s++;
}

int main()
{
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            cin >> map[i][j];
    memcpy(backup, map, sizeof(map));
    for (int i = 0; i < 16; ++i)
    {
        int sign = 1;
        for (int j = 0; j < 16; ++j)
            for (int k = 0; k < 16; ++k)
                for (int l = 0; l < 16; ++l){
                    for (int i2 = 0; i2 < 4; ++i2)
                        if (i >> i2 & 1)
                            press(0, i2);
                    for (int i2 = 0; i2 < 4; ++i2)
                        if (j >> i2 & 1)
                            press(1, i2);
                    for (int i2 = 0; i2 < 4; ++i2)
                        if (k >> i2 & 1)
                            press(2, i2);
                    for (int i2 = 0; i2 < 4; ++i2)
                        if (l >> i2 & 1)
                            press(3, i2);
                        for (int j = 0; j < 4; ++j)
                            for (int k = 0; k < 4; ++k)
                                if (map[j][k] == '+')
                                    sign = 0;
                        if (sign && s < Min)
                        {
                            memcpy(result, list, sizeof(list));
                            Min = s;
                        }
                        memcpy(map, backup, sizeof(map));
                        s = 0;
                        sign = 1;
                    }
    }
    cout << Min << endl;
    for (int i = 0; i < Min; ++i)
        cout << result[i].x << " " << result[i].y << endl;
        return 0;
}

 首先这题不像我之前写的费解的开关那题可以递推,所以其实在我想了很久之后发现,直接暴力枚举!稍微借鉴了一点那题的思路,用四重循环的十进制代表二进制01,就是操作或者不操作,其实也可以变成一个16位的二进制数但那样写有点费脑子,我懒降低了代码可读性,所以没那么写。然后就很简单了。总体而言其实思维量是更小的,可惜我老想找规律浪费一个多小时。

by————2024.1.30刷题记录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值