关灯1
2024年12月24日大约 2 分钟
位运算写法
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000;
const int MAXM = 10;
int n, m;
int a[MAXN + 5];
int aa[MAXN + 5];
int cnt(int x)
{
int res = 0;
while (x > 0)
{
res += 1;
x -= (x & (-x));
}
return res;
}
int main()
{
cin >> n >> m;
int mask = (1 << m) - 1;
for (int i = 0; i < n; i++)
{
a[i] = 0;
for (int j = 0; j < m; j++)
{
int x;
cin >> x;
a[i] = a[i] * 2 + x;
}
}
int ans = -1;
for (int first = 0; first <= (1 << m) - 1; first++)
{
for (int i = 0; i < n; i++)
aa[i] = a[i];
int now = cnt(first);
aa[0] ^= first;
aa[0] ^= (first >> 1);
aa[0] ^= ((first << 1) & mask);
aa[1] ^= first;
for (int i = 1; i < n; i++)
{
now += cnt(aa[i - 1]);
aa[i] ^= aa[i - 1];
aa[i] ^= (aa[i - 1] >> 1);
aa[i] ^= ((aa[i - 1] << 1) & mask);
aa[i + 1] ^= (aa[i - 1]);
}
if (aa[n - 1] == 0 && (ans == -1 || now < ans))
ans = now;
}
cout << ans << "\n";
return 0;
}
dfs 枚举第一行的写法
#include <bits/stdc++.h>
using namespace std;
int n, m;
int a[1005][15];
int b[1005][15]; // 记录那些位置操作了
int ans;
// 计算 a[x][y] 在当前按键情况下的亮灯情况
int cal(int x, int y)
{
int sum = 0;
sum += a[x][y];
sum += b[x][y];
sum += b[x - 1][y];
sum += b[x + 1][y];
sum += b[x][y - 1];
sum += b[x][y + 1];
return sum % 2;
}
// 当前枚举第一排的第 pos 个位置
void dfs(int pos)
{
if (pos == m + 1)
{
// 第一行的前 m 个都按完了,先清空一下下面 2~n 行的案件情况
for (int i = 2; i <= n; i++)
for (int j = 1; j <= m; j++)
b[i][j] = 0;
// 枚举第 2~n 行分别怎么按
for (int i = 2; i <= n; i++)
// 如果上一行的这个位置是一个 1,那么这一行的这个位置就需要按
for (int j = 1; j <= m; j++)
if (cal(i - 1, j) == 1)
b[i][j] = 1;
// 按完了,此时 1~n-1 行全对了,只需要检查最后一行对不对了
bool flag = true;
for (int j = 1; j <= m; j++)
if (cal(n, j) == 1)
flag = false;
// 尝试更新答案
if (flag)
{
// 算算按了几个位置
int cnt = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (b[i][j])
cnt++;
if (ans == -1 || cnt < ans)
ans = cnt;
}
return;
}
b[1][pos] = 0;
dfs(pos + 1); // 不按
b[1][pos] = 0;
b[1][pos] = 1;
dfs(pos + 1); // 按
b[1][pos] = 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
ans = -1;
dfs(1);
cout << ans;
return 0;
}