先贴个题目:
以及原题链接: 116. 飞行员兄弟 - AcWing题库https://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刷题记录