2017.10.28
set中存放的是,所有的开关情况的组合
res中存放的是,根据开关情况,计算出来的灯泡的亮灭的情况的组合。
值得注意的是,当m和n过大的时候,只需要关注 n%6个灯 在 m%16次操作之后的情况就可以了。
public class Solution {
/*
* @param : number of lights
* @param : number of operations
* @return: the number of status
*/
public static int flipLights(int n, int m) {
/***set表示有几种拨动开关的操作,也就是相当于找到所有的四个数相加等于m的组合。
* 这里采用了一个小递归的方法. d[m] = d[m-1] + 1;
* 就可以找到所有的操作方案。
* 对一个开关操作偶数次,等于不操作。
* ***/
if(n >= 11){
n = n%6 + 6;
}
if(m >= 16){
m = m%16;
}
HashSet<ArrayList<Integer>> set = new HashSet<>();
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0);
list.add(0);
list.add(0);
list.add(0);
set.add(list);
for(int i = 1; i <= m; i++){
HashSet<ArrayList<Integer>> setM = new HashSet<>();
for(ArrayList<Integer> listTmp : set){
for(int t = 0; t <= 3; t++){
ArrayList<Integer> listM = new ArrayList<Integer>();
listM.addAll(listTmp);
listM.set(t, listM.get(t) + 1);
setM.add(listM);
}
}
set.clear();
set.addAll(setM);
}
HashSet<String> res = new HashSet<>();
for(ArrayList<Integer> listTmp : set){
int[] lumb = new int[n];
Arrays.fill(lumb, 1);
for(int i = 0; i < 4; i++){
int turn = listTmp.get(i)%2;
switch(i){
case 0:
if(turn == 1){//第一个开关,全部开变关,关变开
for(int j = 0; j < n; j++){
lumb[j] = (lumb[j] + 1)%2;
}
}
break;
case 1:
if(turn == 1){//第二个开关,控制偶数
for(int j = 0; j <= n/2 && 2*j+1<n; j++){
lumb[2*j+1] = (lumb[2*j+1] + 1)%2;
}
}
break;
case 2:
if(turn == 1){//第三个开关,控制奇数
for(int j = 0; j <= n/2 && 2*j<n; j++){
lumb[2*j] = (lumb[2*j] + 1)%2;
}
}
break;
case 3:
if(turn == 1){//第四个开关,控制3k+1
for(int j = 0; j <= n/3 && 3*j<n; j++){
lumb[3*j] = (lumb[3*j] + 1)%2;
}
}
break;
default:
}
}
String s = "";
for(int i = 0; i < n; i++){
s = s + " " + Integer.toString(lumb[i]);
}
res.add(s);
}
for(String s: res){
//System.out.println(s);
}
return res.size();
}
};