题目:
题目描述
在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码。 这些灯都连接到四个按钮:
按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄灭,本来是关着的灯被点亮。
按钮2:当按下此按钮,将改变所有奇数号的灯。
按钮3:当按下此按钮,将改变所有偶数号的灯。
按钮4:当按下此按钮,将改变所有序号是3*K+1(K>=0)的灯。例如:1,4,7...
一个计数器C记录按钮被按下的次数。当宴会开始,所有的灯都亮着,此时计数器C为0。
你将得到计数器C(0<=C<=10000)上的数值和经过若干操作后某些灯的状态。写一个程序去找出所有灯最后可能的与所给出信息相符的状态,并且没有重复。
输入输出格式
输入格式:
不会有灯会在输入中出现两次。
第一行: N。
第二行: C最后显示的数值。
第三行: 最后亮着的灯,用一个空格分开,以-1为结束。
第四行: 最后关着的灯,用一个空格分开,以-1为结束。
输出格式:
每一行是所有灯可能的最后状态(没有重复)。每一行有N个字符,第1个字符表示1号灯,最后一个字符表示N号灯。0表示关闭,1表示亮着。这些行必须从小到大排列(看作是二进制数)。
如果没有可能的状态,则输出一行'IMPOSSIBLE'。
输入输出样例
输入样例#1:
10 1 -1 7 -1输出样例#1:
0000000000 0101010101 0110110110
思路:
灯的个数可能很多,但是不难发现,灯的开关规律是6位一循环的,排列方式也就是ABCDEFABCDEFAB……这样的。
而这前6位数也只有8种情况,即:
000000
001110
010101
011011
100100
101010
110001
111111
可以通过十进制数存储:
000000 —— 0
001110 —— 14
010101 —— 21
011011 —— 27
100100 —— 36
101010 —— 42
110001 —— 49
111111 —— 63
可已发现按3次按以上每一种情况都可出现,而0、1、2次则要单独判断哪些情况可以按出来。
找出有可以按出的情况后就要判断是否符合题目要求的开关情况,此时只需把一个数的二进制拆出来判断即可。
bool judge(int x) {
for(int i=1; i<=6; i++) {
bool y=x%2;
x/=2;
if((y==false&&on[6-i+1])||(y==true&&off[6-i+1])) {
return false;
}
}
return true;
}
打印时要控制长度:
void print(int x) {
int two[7]= {0};
for(int i=1; i<=6; i++) {
int y=x%2;
x/=2;
two[6-i+1]=y;
}
for(int i=1; i<=n; i++) {
int y=i%6;
if(y==0) y=6;
printf("%d",two[y]);
}
printf("\n");
return ;
}
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int a[10]= {0,0,14,21,27,36,42,49,63};
int n,C;
bool on[6],off[6];
bool judge(int x) {
for(int i=1; i<=6; i++) {
bool y=x%2;
x/=2;
if((y==false&&on[6-i+1])||(y==true&&off[6-i+1])) {
return false;
}
}
return true;
}
void print(int x) {
int two[7]= {0};
for(int i=1; i<=6; i++) {
int y=x%2;
x/=2;
two[6-i+1]=y;
}
for(int i=1; i<=n; i++) {
int y=i%6;
if(y==0) y=6;
printf("%d",two[y]);
}
printf("\n");
return ;
}
int main() {
scanf("%d%d",&n,&C);
int x;
while(scanf("%d",&x)&&x!=-1) {
int y=x%6;
if(y==0) y=6;
on[y]=true;
}
while(scanf("%d",&x)&&x!=-1) {
int y=x%6;
if(y==0) y=6;
if(on[y]==true) {
printf("IMPOSSIBLE");
return 0;
}
off[y]=true;
}
bool flag=false;
if(C>=3) {
for(int i=1; i<=8; i++) {
if(judge(a[i])) {
print(a[i]);
flag=true;
}
}
}
if(C==0) {
if(judge(63)) {
print(63);
flag=true;
}
}
if(C==1) {
if(judge(0)) {
print(0);
flag=true;
}
if(judge(21)) {
print(21);
flag=true;
}
if(judge(42)) {
print(42);
flag=true;
}
if(judge(27)) {
print(27);
flag=true;
}
}
if(C==2) {
if(judge(0)) {
print(0);
flag=true;
}
if(judge(14)) {
print(14);
flag=true;
}
if(judge(21)) {
print(21);
flag=true;
}
if(judge(36)) {
print(36);
flag=true;
}
if(judge(42)) {
print(42);
flag=true;
}
if(judge(49)) {
print(49);
flag=true;
}
if(judge(63)) {
print(63);
flag=true;
}
}
if(flag==false) {
printf("IMPOSSIBLE");
}
return 0;
}