LeetCode/灯泡开关
作者:互联网
1. 灯泡开关I
初始时有 n 个灯泡处于关闭状态,第i轮切换i的倍数位置的开关,直到第n轮切换位置n的灯泡开关,返回n轮后灯泡亮着个数
实际上就是求进行奇数次操作灯泡个数,对第k个灯泡进行操作的轮次为其约数,约数一般成对存在,除非为完全平方数
原问题转换为求1~n的完全平方数个数
return (int)pow(n,0.5);
2. 灯泡开关II
房间中有 n 只已经打开的灯泡,编号从 1 到 n ,墙上挂着 4 个开关
- 开关 1 :反转当前所有灯的状态(即开变为关,关变为开)
- 开关 2 :反转编号为偶数的灯的状态(即 2, 4, 6, 8, 10)
- 开关 3 :反转编号为奇数的灯的状态(即 1, 3, 5, 7, 9, 11)
- 开关 4 :反转编号为 j = 3k + 1 的灯的状态,其中 k = 0, 1, 2, ...(即 1, 4, 7, 10, ...)
给你两个整数 n 和 presses,执行完所有按压之后,返回不同可能状态的数量
已知开关1影响所有灯泡,编号为6k+1受开关3,4影响,编号6k+4受开关2,4影响
编号6k+2,6k+6受开关2影响, 编号6k+3,6k+5受开关3影响
实际上前4个灯泡的状态,已经决定了后面所有灯泡状态
接下来遍历所有开关状态(16种),求解对应四个灯泡状态即可
class Solution {
public:
int flipLights(int n, int presses) {
unordered_set<int> s;
for (int i = 0; i < 1 << 4; i++) {//遍历4位的全排列,即16种开关状态
vector<int> pressArr(4);
for (int j = 0; j < 4; j++) //将开关状态4位二进制转化成数组形式,便于后续计算
pressArr[j] = (i >> j) & 1;
int sum = accumulate(pressArr.begin(), pressArr.end(), 0);
if (sum % 2 == presses % 2 && sum <= presses) {//开关状态奇偶性应该与操作数一致
int status = pressArr[0] ^ pressArr[1] ^ pressArr[3];//灯泡1状态依赖
if (n >= 2)
status |= (pressArr[0] ^ pressArr[1]) << 1;//灯泡2状态依赖,并移到第二位
if (n >= 3)
status |= (pressArr[0] ^ pressArr[2]) << 2;//灯泡3状态依赖,并移到第三位
if (n >= 4)
status |= (pressArr[0] ^ pressArr[1] ^ pressArr[3]) << 3;//灯泡4状态依赖
s.emplace(status);//用4位二进制数表示灯泡状态
}
}
return s.size();
}
};
标签:int,pressArr,6k,灯泡,开关,编号,LeetCode 来源: https://www.cnblogs.com/929code/p/16695159.html