ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

「费解的开关」题解

2021-08-23 22:35:07  阅读:146  来源: 互联网

标签:开关 int 题解 费解 tot ++ MAXN ans check


「费解的开关」题解

原题目链接:Link

这道题,我们可以先枚举第一行的所有情况,根据第一行的情况来依次确定如何改变。显然:

  1. 每个灯要么改变要么不改变,即最多改变 \(1\) 次;
  2. 当第一行被固定后,只会有一种方案使全部灯都亮着;
  3. 若第 \(i\) 行已经被固定,且第 \(j\) 个灯灭着,我们就必须按处于 \((i + 1, j)\) 的灯(下一行的灯)。

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 10;

int n, ans;
bool a[MAXN][MAXN], b[MAXN][MAXN];
string s;

bool check(int x, int y) {return x >= 0 && y >= 0;}

void mov(int x, int y) {
	if (check(x, y)) a[x][y] ^= 1;
	if (check(x - 1, y)) a[x - 1][y] ^= 1;
	if (check(x + 1, y)) a[x + 1][y] ^= 1;
	if (check(x, y - 1)) a[x][y - 1] ^= 1;
	if (check(x, y + 1)) a[x][y + 1] ^= 1; // 模拟开灯,为了防止越界引入 check 函数
}
int main() {
	scanf("%d", &n);
	while (n--) {
		getline(cin, s); ans = 0x7ffffff;
		for (int i = 0; i < 5; i++) {
			cin >> s;
			for (int j = 0; j < 5; j++)
				b[i][j] = a[i][j] = s[j] == '1'; // 因为要在 a 数组上操作,所以用一个 b 数组记录初始数组
		}
		for (int now = 0; now < 1 << 5; now++) { // 二进制枚举第一行的所有情况
			memcpy(a, b, sizeof(b)); // 操作完 a 数组,把原来的复制过来
			int tot = 0, t;
			for (int bit = 0; bit < 5; bit++) {
				int t = now >> bit & 1; // now 的第 bit 位
				if (a[0][bit] != t) {
					mov(0, bit);
					tot++;
				}
			} // 按 now 改变 a 数组的第一行,同时记录操作次数,不同就 tot++
			for (int i = 1; i < 5; i++)
				for (int j = 0; j < 5; j++) {
					if (!a[i - 1][j]) { // 如果这个位置的上一行的灯灭了
						mov(i, j); // 按这个位置,同时 tot++
						tot++;
					}
				}
			bool flag = true;
			for (int i = 0; i < 5; i++)
				if (!a[4][i]) {flag = false; break;} // 最后扫一遍数组,看是不是全部开着
			if (flag) ans = min(ans, tot); // 是就记录答案
		}
		if (ans <= 6) printf("%d\n", ans);
		else puts("-1"); // 这里不能直接输出,还要判断是否 <= 6
	}
    return 0;
}

标签:开关,int,题解,费解,tot,++,MAXN,ans,check
来源: https://www.cnblogs.com/liuzimingc/p/open-close.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有