P1468 派对灯 Party Lamps
我们来分析一下对灯的操作
1.对所有灯的,这时吧所有灯看成一个整体
2.奇偶数的操作,这时可以把每两个数看成一个循环节
3.对3X+ 1的操作,这时可以把每三个数看成一个循环节
显而易见的,我们把序列看成6个一组的循环节,便能模拟整个序列。
用笔画一下,我们发现将这个含六个元素的序列进行变换最终只会有八种结果,那么我们只需要判断一下最后这八种结果
最后是否符合题意要求就行了(至于他是怎么变换的我们不用管)
以上就是在题解区找到的解释,其实说得很好,希望原作者 fastle 见谅。

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1e3+10; 4 int One[N],Zero[N],cnt1,cnt2; 5 int n,C; 6 int a[N][16]; 7 string S[100]; 8 char s[N]; 9 void Init(){ 10 for(int i=0;i<N;i++){ 11 for(int j=0;j<=15;j++){ 12 a[i][j] = 1; 13 } 14 } 15 } 16 inline bool check( int No ){ 17 int cnt = 0 ; 18 for(int i=0;i<4;i++){ 19 if( (No & (1<<i)) == (1<<i) ) 20 cnt++; 21 } 22 bool F = (cnt<=C) ; 23 for(int i=0;i<cnt1;i++){ 24 if( a[One[i]][No] != 1 ) F = false; 25 } 26 for(int i=0;i<cnt2;i++){ 27 if( a[Zero[i]][No] != 0 ) F = false; 28 } 29 return F; 30 } 31 int main() 32 { 33 ios_base :: sync_with_stdio(0); 34 cin.tie(NULL) , cout.tie(NULL); 35 Init(); 36 cin>>n>>C; 37 while( cin>>One[cnt1++] ){ 38 if(One[cnt1-1]==-1){ 39 cnt1--; break; 40 } 41 } 42 while( cin>>Zero[cnt2++] ){ 43 if(Zero[cnt2-1]==-1){ 44 cnt2--; break; 45 } 46 } 47 /* 48 for(int i=0;i<cnt1;i++){ 49 printf("%d%c",One[i],i==cnt1-1?' ':' '); 50 } 51 for(int i=0;i<cnt2;i++){ 52 printf("%d%c",Zero[i],i==cnt2-1?' ':' '); 53 } 54 */ 55 for(int i=0;i<=15;i++){ 56 if( i & 1 ){ 57 for(int j=1;j<=n;j++){ 58 a[j][i] = a[j][i] ^ 1 ; 59 } 60 } 61 if( (i>>1) & 1 ){ 62 for(int j=1;j<=n;j+=2){ 63 a[j][i] = a[j][i] ^ 1 ; 64 } 65 } 66 if( (i>>2) & 1 ){ 67 for(int j=2;j<=n;j+=2){ 68 a[j][i] = a[j][i] ^ 1 ; 69 } 70 } 71 if( (i>>3) & 1 ){ 72 for(int j=1;j<=n;j+=3){ 73 a[j][i] = a[j][i] ^ 1 ; 74 } 75 } 76 } 77 int cnt = 0 ; 78 79 for(int j=0;j<=15;j++){ 80 if( check(j) ) { 81 for(int i = 1 ; i <= n; i++){ 82 s[i-1] = a[i][j] + '0'; 83 } 84 s[n] = '