Solution of USACO 2023.Jan Au T2 Light Off
好久不更了,找到一个很不错的题,写一下题解。
题意简化
有
思考算法
先来看数据范围
如果选择预处理灯的所有状态以及开关的所有状态,总状态数就是
问题来了:我们预处理灯的状态还是开关的状态呢?很显然是灯的状态,因为最后要求把灯都关掉,开关关不关无所谓。
深度分析
可是不难发现开关的状态对最少步数也有影响,我们考虑把开关的影响消去。并且,预处理灯的状态时需要设定一个开关的状态才可以,姑且先把开关的状态全部设成
我们发现操作二和操作三是自动的,即不需要选择的。为了消除影响,要把我的开关和实际开关联系起来。
于是把
但是我们仍然需要认识到对我的开关进行单点修改相当于对实际开关进行单点修改。(理解不了看完后面的再来看可能更好理解,不懂的话先忽略)
具体操作
每一轮先用实际开关,
可是这样每一轮还是很棘手,我们发现对我的开关进行单点修改操作可以留着想做的时候一起做就行了,预处理一下就完事儿,预处理的东西就是灯的状态为
For example:
Example 1:
000
101
初始时我们先看灯的状态为 000,开关的状态为 000 时,能否
Example 2:
101
100
先看灯的状态为 101,开关的状态还是 000 时(下文省略不写),能否用
第二轮时我们先看把之前的操作都用上能否关掉。即灯为 001时能不能一步关掉,发现可以,那么就把当初的单点修改做了。答案为轮数减一,
(注:此时若想一步用 000开关关掉 001 仅需要给第三个开关做单点修改。那么就相当于给实际开关第三个地方做单点修改啦!就是在第一步时把实际开关变成 ``101``)
如果你觉得有一点理解了,那么再来看最后这个:
Example 3:
1000
1011
可以自己先模拟一下,再来看我的过程。
首先看灯的状态为 1000 能否
第二轮开始前看一下灯的状态为 0011 能否
第三轮之前再看下灯为 1110,能否
补充:方法是先单点修改第一个开关,然后灯变成 0110,开关旋转变成 0100,再单点修改第三个就行。把对我的开关的操作移动到实际开关上看一看?第一轮单点修改第一个,变成 0011,灯变成 1011,开关旋转后变成 1001。接着第二轮修改第三个,变成 1011,正好搞定,我们的方法是对的。
后话:官方题解加了个优化,去掉了个
(话说这题时限为啥不开到
因为我懒,所以给个
#include<iostream> using namespace std; string s,t; int T, n; int g[45][22], mask[22]; bool f[45][1 << 21] = { {1} }; int calc (int s, int t) { if (s == 0) return 0; for (int i = 1; i <= 2 * n; i ++) { int vis = s; for (int j = 0; j < n; j ++) if (t & (1 << j) ) vis = vis ^ g[i][j]; if (f[i][vis]) return i; } return -1; } int main() { cin >> T >> n; for (int i = 0; i <= n; i ++) mask[i] = 1 << i; int N = 1 << n; for (int k = 0; k < n; k ++) for (int i = 1; i <= 2 * n; i ++) for (int j = 0; j < i; j ++) g[i][k] ^= mask[(k + j) % n]; for (int i = 1; i <= 2 * n; i ++) for (int j = 0; j < N; j ++) { if (!f[i - 1][j]) continue; for (int k = 0; k < n; k ++){ int vis = j; vis ^= g[i][k]; f[i][vis] = 1; } } while (T --){ cin >> s >> t; int S = 0, T = 0; for (int i = 0; i < n; i ++) { if (s[i] == '1') S ^= (1 << i); if (t[i] == '1') T ^= (1 << i); } cout << calc(S, T) << "\n"; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异