专栏文章

题解:P1161 开灯

P1161题解参与者 8已保存评论 12

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
12 条
当前快照
1 份
快照标识符
@mip4inst
此快照首次捕获于
2025/12/03 06:02
3 个月前
此快照最后确认于
2025/12/03 06:02
3 个月前
查看原文

题目分析

给定一个无限长的序列,初始时所有灯都是关闭状态。进行 nn 次操作,每次操作给定 aatt,将编号为a,2×a,,t×a\left \lfloor a \right \rfloor,\left \lfloor 2\times a \right \rfloor, \dots ,\left \lfloor t\times a \right \rfloor 的灯的状态切换。经过所有操作后,只有一盏灯是开着的,我们需要找出这盏灯的编号。

解题思路

每次操作实际上是转换灯的状态。我们可以用一个数组来记录每个灯被切换的次数。
初始时所有灯的状态为 00。对于每次操作,计算 i×a\left \lfloor i\times a \right \rfloorii 是从 11tt),并将对应位置的数异或 11(根据异或的性质可知,这其实就是状态转换)。
代码时间复杂度为 O(n×t)O(n\times t),包能过的。

代码实现

CPP
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2000001;
int light[MAXN];//状态表示。
int n, t;
double a;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a >> t;
        for (int j = 1; j <= t; j++) {
            int index = (int)(j * a);
            light[index] ^= 1;//切换状态。
        }
    }
    //找出唯一亮着的灯。
    for (int i = 2; i <= MAXN; i++) {
        if (light[i] == 1) {
            cout << i << endl;
            break;
        }
    }
    
    return 0;
}
update: 2025.7.24 修复了一处错误。

评论

12 条评论,欢迎与作者交流。

正在加载评论...