房间中有 n
只已经打开的灯泡,编号从 1
到 n
。墙上挂着 4 个开关 。
这 4 个开关各自都具有不同的功能,其中:
- **开关 1 :**反转当前所有灯的状态(即开变为关,关变为开)
- **开关 2 :**反转编号为偶数的灯的状态(即
2, 4, ...
) - **开关 3 :**反转编号为奇数的灯的状态(即
1, 3, ...
) - **开关 4 :**反转编号为
j = 3k + 1
的灯的状态,其中k = 0, 1, 2, ...
(即1, 4, 7, 10, ...
)
你必须 恰好 按压开关 presses
次。每次按压,你都需要从 4 个开关中选出一个来执行按压操作。
给你两个整数 n
和 presses
,执行完所有按压之后,返回 不同可能状态 的数量。
示例 1:
输入:n = 1, presses = 1
输出:2
解释:状态可以是:
- 按压开关 1 ,[关]
- 按压开关 2 ,[开]
示例 2:
输入:n = 2, presses = 1
输出:3
解释:状态可以是:
- 按压开关 1 ,[关, 关]
- 按压开关 2 ,[开, 关]
- 按压开关 3 ,[关, 开]
示例 3:
输入:n = 3, presses = 1
输出:4
解释:状态可以是:
- 按压开关 1 ,[关, 关, 关]
- 按压开关 2 ,[关, 开, 关]
- 按压开关 3 ,[开, 关, 开]
- 按压开关 4 ,[关, 开, 开]
提示:
1 <= n <= 1000
0 <= presses <= 1000
解题思路
- 模拟四种操作
- 按压超过4次,与4次的结果相同
- 字符串长度超过6,与长度=6的结果相同
class Solution {
public:
// 需要声明称静态函数
static string op0(string& str){
return bitset<6>(str).flip().to_string();
}
static string op1(string& str){
bitset<6> b(str);
for(int i=0; i<6; i+=2){
b.flip(i);
}
return b.to_string();
}
static string op2(string& str){
bitset<6> b(str);
for(int i=1; i<6; i+=2){
b.flip(i);
}
return b.to_string();
}
static string op3(string& str){
bitset<6> b(str);
for(int i=0; i<6; i+=3){
b.flip(i);
}
return b.to_string();
}
void dfs(string str, int presses, int n){
if(presses==0){
uset.insert(str.substr(str.size()-n));
return;
}
for(int i=0; i<4; i++){
string tmp = vec[i](str);
dfs(tmp, presses-1, n);
}
}
vector<function<string(string&)>> vec = {op0, op1, op2, op3};
unordered_set<string> uset;
int flipLights(int n, int presses) {
string bulb = "111111"; //反方向;
if(presses==0) return 1;
presses = min(4, presses);
n = min(6, n);
dfs(bulb, presses, n);
return uset.size();
}
};
No party has a monopoly on wisdom. No democracy works without compromise. But when Governor Romney and his allies in Congress tell us we can somehow lower our deficit by spending trillions more on new tax breaks for the wealthy - well, you do the math. I refuse to go along with that. And as long as I’m President, I never will.
— Barack Obama