Party Lamps
IOI 98
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,...
A counter C records the total number of button presses.
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
No lamp will be listed twice in the input.
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.
SAMPLE INPUT (file lamps.in)
10
1
-1
7 -1
In 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
0110110110
In 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.
题意:题目给出了几种操作灯的方法1代表全部的灯要变化,2代表只变化奇数的灯,3代表只变化偶数的灯,4代表变化3K+1(k>=0)。灯笼数目N,对灯的操作次数C,最后依然亮着的灯,最后灭掉的灯。要求输出最后所有灯可能的情况。
思路:首先,明确一点前六个灯的状态可代表后面所有的灯,也就是说是每六个一循环的。为什么是这样呢?1操作发生变化的循环节为1,2操作和3操作发生变化的循环节是2,4操作发生变化的循环节是3,所以总的灯笼发生变化的循环节是1,2,3的公倍数,就是6了。其次,当输入的C>4时,操作中必定有重复的操作,而同一个操作做两遍其实对于灯来说是没有什么变化的。所以我们可以对灯的操作次数不断的减2,操作次数<=4。明白了这两点解题就容易多了,数据规模缩小了,只要枚举每种可能就可以了。
源代码:
/*
ID: supersnow0622
PROG: test
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include<memory.h>
#include<algorithm>
using namespace std;
int on[110],off[110],lamp[7],used[64],start=63,state,N,C,a=0;
string s[300];
void change(int n,int m)
{
switch (n){
case 1:state=m xor 63;break;
case 2:state=m xor 42;break;
case 3:state=m xor 21;break;
case 4:state=m xor 36;break;
}
}
bool convert()
{
int tempstate=state;
if(used[tempstate]==1)
return false;
used[tempstate]=1;
int temp[7],num=6;
memset(temp,0,sizeof(temp));
while(tempstate!=0)
{
temp[num]=tempstate%2;
if(lamp[num]!=-1&&temp[num]!=lamp[num])
return false;
num--;
tempstate/=2;
}
if(lamp[1]!=-1&&lamp[1]!=temp[1])
return false;
int m=N/6,n=N%6;
for(int i=0;i<m;i++)
for(int j=1;j<7;j++)
s[a]+=temp[j]+'0';
for(int i=1;i<=n;i++)
s[a]+=temp[i]+'0';
a++;
return true;
}
int main() {
ofstream fout ("test.out");
ifstream fin ("test.in");
int count=0,ok2,ok3,ok4;
cin>>N>>C;
while(cin>>on[count]&&on[count]!=-1)
count++;
memset(lamp,-1,sizeof(lamp));
for(int i=0;i<count;i++)
if(on[i]%6!=0)
lamp[on[i]%6]=1;
else lamp[6]=1;
count=0;
while(cin>>off[count]&&off[count]!=-1)
count++;
if(C==0)
{
if(count!=0)
{cout<<"IMPOSSIBLE"<<endl;return 0;}
for(int i=0;i<N;i++)
cout<<"1";
cout<<endl;
return 0;
}
for(int i=0;i<count;i++)
if(off[i]%6!=0)
lamp[off[i]%6]=0;
else lamp[6]=0;
while(C>4)
C=C-2;
ok2=ok3=ok4=0;
int judge=0;
memset(used,0,sizeof(used));
if(C==2) ok2=1;
if(C==3) ok2=ok3=1;
if(C==4) ok2=ok3=ok4=1;
judge=0;
for(int i=1;i<=4;i++)
{
for(int j=1;ok2==1&&j<=4;j++)
{
for(int k=1;ok3==1&&k<=4;k++)
{
for(int l=1;ok4==1&&l<=4;l++)
{
change(i,start);
change(j,state);
change(k,state);
change(l,state);
if(convert()) judge++;
}
if(ok4==0)
{
change(i,start);
change(j,state);
change(k,state);
if(convert()) judge++;
}
}
if(ok3==0)
{
change(i,start);
change(j,state);
if(convert()) judge++;
}
}
if(ok2==0)
{
change(i,start);
if(convert()) judge++;
}
}
if(!judge)
cout<<"IMPOSSIBLE"<<endl;
else {
sort(s,s+a);
for(int i=0;i<a;i++)
cout<<s[i]<<endl;
}
return 0;
}