题目:
题目描述
在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;
}