partylamps - codetrick
To brighten up the gala dinner of the IOI'98 we have a set of N (10 <= N <= 100) colored lamps numbered from 1 to N.
The lamps are connected to four buttons:
When the party starts, all the lamps are ON and the counter C is set to zero.
You are given the value of counter C (0 <= C <= 10000) and the final state of some of the lamps after some operations have been executed. Write a program to determine all the possible final configurations of the N lamps that are consistent with the given information, without repetitions.
If there are no possible configurations, output a single line with the single word `IMPOSSIBLE'
总共就4个按钮...如果我1,2,3,4都按过一次了..再按一下1 or 2 or 3 or 4灯的情况不和只按了2,3,4 or 1,3,4 or 1,2,4 or 1,2,3一样吗?因为一个按钮按两次就相当于没按..那么实际上能出现的最多情况也就是C(1,4)+C(2,4)+C(3,4)+C(4,4)=17种~~枚举出这些情况..当且仅当当前所案件的次数与所需要的按键次数之差为偶数(不断地来回按)并且得到的情况是满足输入的要求的就找到了一个~~
https://github.com/TomConerly/Competition-Programming/blob/master/USACO/Chapter2/lamps.java
http://jackneus.com/programming-archives/party-lamps/
https://www.byvoid.com/blog/usaco-224-party-lamps
X. Brute Force: 4^C
http://lujunda.cn/2012/08/04/usacosection-2-2%E6%90%9C%E7%B4%A2-party-lamps/
http://lsharemy.com/wordpress/index.php/csit/usaco-prob-party-lamps/
Read full article from partylamps - codetrick
To brighten up the gala dinner of the IOI'98 we have a set of N (10 <= N <= 100) colored lamps numbered from 1 to N.
The lamps are connected to four buttons:
- Button 1: When this button is pressed, all the lamps change their state: those that are ON are turned OFF and those that are OFF are turned ON.
- Button 2: Changes the state of all the odd numbered lamps.
- Button 3: Changes the state of all the even numbered lamps.
- Button 4: Changes the state of the lamps whose number is of the form 3xK+1 (with K>=0), i.e., 1,4,7,...
When the party starts, all the lamps are ON and the counter C is set to zero.
You are given the value of counter C (0 <= C <= 10000) and the final state of some of the lamps after some operations have been executed. Write a program to determine all the possible final configurations of the N lamps that are consistent with the given information, without repetitions.
PROGRAM NAME: lamps
INPUT FORMAT
| Line 1: | N |
| Line 2: | Final value of C |
| Line 3: | Some lamp numbers ON in the final configuration, separated by one space and terminated by the integer -1. |
| Line 4: | Some lamp numbers OFF in the final configuration, separated by one space and terminated by the integer -1. |
| No lamp will be listed twice in the input. |
SAMPLE INPUT (file lamps.in)
10
1
-1
7 -1In this case, there are 10 lamps and only one button has been pressed. Lamp 7 is OFF in the final configuration.
OUTPUT FORMAT
Lines with all the possible final configurations (without repetitions) of all the lamps. Each line has N characters, where the first character represents the state of lamp 1 and the last character represents the state of lamp N. A 0 (zero) stands for a lamp that is OFF, and a 1 (one) stands for a lamp that is ON. The lines must be ordered from least to largest (as binary numbers).If there are no possible configurations, output a single line with the single word `IMPOSSIBLE'
SAMPLE OUTPUT (file lamps.out)
0000000000 0101010101 0110110110In this case, there are three possible final configurations:
- All lamps are OFF
- Lamps 1, 4, 7, 10 are OFF and lamps 2, 3, 5, 6, 8, 9 are ON.
- Lamps 1, 3, 5, 7, 9 are OFF and lamps 2, 4, 6, 8, 10 are ON.
总共就4个按钮...如果我1,2,3,4都按过一次了..再按一下1 or 2 or 3 or 4灯的情况不和只按了2,3,4 or 1,3,4 or 1,2,4 or 1,2,3一样吗?因为一个按钮按两次就相当于没按..那么实际上能出现的最多情况也就是C(1,4)+C(2,4)+C(3,4)+C(4,4)=17种~~枚举出这些情况..当且仅当当前所案件的次数与所需要的按键次数之差为偶数(不断地来回按)并且得到的情况是满足输入的要求的就找到了一个~~
这道题目还是暴力枚举,开关按两次以后等于没有按。如果同时按了偶数和奇数按钮等于按了一号按钮,按了一号和偶数等于按了奇数按钮,按了一号和奇数按钮等于按了偶数按钮。
那么无论怎么枚举按钮只可能出现以下8种情况:1.什么都没有按;2.只按了一号按钮;3.只按了奇数按钮;4.只按了偶数按钮;5.只按了3*k+1按钮;6.同时按了一号按钮和3*k+1按钮;7.同时按了奇数按钮和3*k+1按钮;8.同时按了偶数按钮和3*k+1按钮
由于只有以上的8种状态,现在难点就在于如何将这些状态与cnt(按了几次)对应起来。
分析后,我们可以对cnt做如下分类:1. cnt ==0 ;2.cnt ==1;3.cnt==2 ;4.cnt==3;5.cnt>=4,并且cnt为偶数 ;6.cnt>4,并且cnt为奇数
cnt的前四种情况都比较简单,可以直接模拟出。现在讨论第5种和第6种情况,第5种情况等价于cnt==4的情况(因为最多有四个开关,所以cnt>4的时候一定可以找到两个开关作用两两相消除),第6种情况等价于cnt==3(原理同上)。
按照上面说明的情况,我们只需要对输入的cnt进行判断的,然后将该情况可能产生的亮灯状态与输入的开关灯状态比较,如果满足则输出。
https://github.com/TomConerly/Competition-Programming/blob/master/USACO/Chapter2/lamps.java
| public static void main(String[] args) throws IOException { | |
| Scanner sc = new Scanner(new File("lamps.in")); | |
| PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("lamps.out"))); | |
| int N = sc.nextInt(); | |
| int C = sc.nextInt(); | |
| ArrayList<Integer> setOn = new ArrayList<Integer>(); | |
| while(true) | |
| { | |
| int temp = sc.nextInt(); | |
| if(temp == -1) break; | |
| setOn.add(temp-1); | |
| } | |
| ArrayList<Integer> setOff = new ArrayList<Integer>(); | |
| while(true) | |
| { | |
| int temp = sc.nextInt(); | |
| if(temp == -1) break; | |
| setOff.add(temp-1); | |
| } | |
| boolean[] lights = new boolean[N]; | |
| Arrays.fill(lights,true); | |
| r = new boolean[2][2][2][2][N]; | |
| r[0][0][0][0] = lights; | |
| r[0][0][0][1] = move1(lights); | |
| r[0][0][1][0] = move2(lights); | |
| r[0][1][0][0] = move3(lights); | |
| r[1][0][0][0] = move4(lights); | |
| r[0][0][1][1] = move1(move2(lights)); | |
| r[0][1][0][1] = move1(move3(lights)); | |
| r[1][0][0][1] = move1(move4(lights)); | |
| r[0][1][1][0] = move2(move3(lights)); | |
| r[1][0][1][0] = move2(move4(lights)); | |
| r[1][1][0][0] = move3(move4(lights)); | |
| r[1][1][1][0] = move2(move3(move4(lights))); | |
| r[1][1][0][1] = move1(move3(move4(lights))); | |
| r[1][0][1][1] = move1(move1(move4(lights))); | |
| r[0][1][1][1] = move1(move2(move3(lights))); | |
| r[1][1][1][1] = move1(move2(move3(move4(lights)))); | |
| ArrayList<Answer> list = new ArrayList<Answer>(); | |
| for(int i = 0; i < 2;i++) | |
| { | |
| for(int j = 0; j < 2;j++) | |
| { | |
| for(int k = 0; k < 2;k++) | |
| { | |
| for(int m = 0; m < 2;m++) | |
| { | |
| if(C-i-j-k-m >= 0 && (C-i-j-k-m)%2 == 0) | |
| { | |
| boolean legal = true; | |
| for(int on:setOn) | |
| { | |
| if(!r[i][j][k][m][on])legal = false; | |
| } | |
| for(int off:setOff) | |
| { | |
| if(r[i][j][k][m][off])legal = false; | |
| } | |
| if(legal) list.add(new Answer(i,j,k,m)); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| Collections.sort(list); | |
| for(Answer a: list) | |
| { | |
| out.println(a.toString()); | |
| } | |
| if(list.size() == 0) | |
| out.println("IMPOSSIBLE"); | |
| out.close(); | |
| } | |
| static boolean[][][][][] r; | |
| private static class Answer implements Comparable<Answer> | |
| { | |
| int i,j,k,m; | |
| public Answer(int a, int b, int c, int d) | |
| { | |
| i=a; | |
| j=b; | |
| k=c; | |
| m=d; | |
| } | |
| public int compareTo(Answer a) { | |
| for(int t = 0; t < r[0][0][0][0].length;t++) | |
| { | |
| if(r[i][j][k][m][t] && !r[a.i][a.j][a.k][a.m][t]) return 1; | |
| if(!r[i][j][k][m][t] && r[a.i][a.j][a.k][a.m][t]) return -1; | |
| } | |
| return 0; | |
| } | |
| public String toString() | |
| { | |
| String out = ""; | |
| for(int t = 0; t < r[0][0][0][0].length;t++) | |
| { | |
| if(r[i][j][k][m][t]) out = out+"1"; | |
| else out = out+"0"; | |
| } | |
| return out; | |
| } | |
| } | |
| public static boolean[] move1(boolean[] in) | |
| { | |
| boolean[] ret = new boolean[in.length]; | |
| for(int i = 0; i < ret.length;i++) | |
| { | |
| ret[i] = !in[i]; | |
| } | |
| return ret; | |
| } | |
| public static boolean[] move2(boolean[] in) | |
| { | |
| boolean[] ret = new boolean[in.length]; | |
| for(int i = 0; i < ret.length;i++) | |
| { | |
| if(i%2 == 1) | |
| ret[i] = !in[i]; | |
| else | |
| ret[i] = in[i]; | |
| } | |
| return ret; | |
| } | |
| public static boolean[] move3(boolean[] in) | |
| { | |
| boolean[] ret = new boolean[in.length]; | |
| for(int i = 0; i < ret.length;i++) | |
| { | |
| if(i%2 == 0) | |
| ret[i] = !in[i]; | |
| else | |
| ret[i] = in[i]; | |
| } | |
| return ret; | |
| } | |
| public static boolean[] move4(boolean[] in) | |
| { | |
| boolean[] ret = new boolean[in.length]; | |
| for(int i = 0; i < ret.length;i++) | |
| { | |
| if(i%3 == 0) | |
| ret[i] = !in[i]; | |
| else | |
| ret[i] = in[i]; | |
| } | |
| return ret; | |
| } |
http://jackneus.com/programming-archives/party-lamps/
https://www.byvoid.com/blog/usaco-224-party-lamps
X. Brute Force: 4^C
http://lujunda.cn/2012/08/04/usacosection-2-2%E6%90%9C%E7%B4%A2-party-lamps/
point op(int t,point temp)//operation操作函数。//参数t表示按钮编号。//temp表示按钮作用的对象状态。{ if(t==1) for(int i=1;i<=n;i++) temp.arry[i]=temp.arry[i]-'0'?'0':'1'; else if(t==2) for(int i=1;i<=n;i+=2) temp.arry[i]=temp.arry[i]-'0'?'0':'1'; else if(t==3) for(int i=2;i<=n;i+=2) temp.arry[i]=temp.arry[i]-'0'?'0':'1'; else for(int i=0;3*i+1<=n;i++) temp.arry[3*i+1]=temp.arry[3*i+1]-'0'?'0':'1'; return temp;}bool check(point temp)//检查temp是否与目标状态相符。{ for(int i=1;i<=n;i++) { if(on[i]&&temp.arry[i]=='0') return false; if(off[i]&&temp.arry[i]=='1') return false; } string result=temp.arry; if(mark[result]) //检查temp是否与其他已确定的状态相重复。 return false; mark[result]=true; return true;}void dfs(point temp,int sum)//利用深搜枚举4^c种状态。{ if(sum==c) { if(check(temp)) res[total++]=temp; return; } for(int i=1;i<5;i++) dfs(op(i,temp),sum+1);}http://lsharemy.com/wordpress/index.php/csit/usaco-prob-party-lamps/
Read full article from partylamps - codetrick