渝渝家里新房子刚刚装了一个华丽的新的枝形吊灯,由 N (3<=N<=16) 个按一个圆圈排
放的灯泡组成。
渝渝对这个新的灯光设备很好奇, 并喜欢玩下面这个游戏: 在时间 T, 如果某个灯
泡左边相邻的那个灯泡在 T-1 时间是开的,则切换这个灯泡的状态。 他在 B 时间内一直玩
这个游戏 (1<=B<=10^15)。
给出所有灯泡的初始状态, 输出在 B 时间后灯泡的最终状态。
输入格式:
第一行: 包含两个用空格隔开的整数, N 和 B。
第 2-1+N 行: 第 i+1 行包含第 i 个灯泡的初始状态, 不是 0(关的)就是 1(开的)。
输出格式:
第1- N 行: 第 i 行包含第 i 个灯泡的最终状态, 不是 0(关)就是 1(开)
。
【输入输出样例】
5 6
1
0
0
0
0
输出
1
1
1
0
1
思路:
状态是循环的,本题最多是2的16次方个状态,所以可以暴力枚举循环节
写个状压,展现水准
code:
#include <cstdio> #include <iostream> #include <map> #define ll long long #define R register using namespace std; int n,num=0,in; ll b; inline void out(int num) { for(R int i=n;i>=1;i--) { if(num&(1<<(i-1))) cout<<1<<endl; else cout<<0<<endl; } cout<<endl; } inline void turn(int &num) { int ynum=num; for(R int i=n;i>=1;i--) if(ynum&(1<<(i-1))) { if(i!=1) { if(ynum&(1<<(i-2))) num-=(1<<(i-2)); else num+=(1<<(i-2)); } else { if(ynum&(1<<(n-1))) num-=(1<<(n-1)); else num+=(1<<(n-1)); } } //out(num); } int mp[100000],top=0; int bo[655360]; int main() { freopen("blink.in","r",stdin); freopen("blink.out","w",stdout); cin>>n>>b; for(R int i=n;i>=1;i--) { cin>>in; if(in) num+=(1<<(i-1)); } int tot=0; ll B=b; while(B--) { tot++; turn(num); mp[++top]=num; if(bo[num]==0) bo[num]=tot; else //if(b>1000000) { //cout<<tot<<endl; //cout<<bo[num]<<" "<<num<<endl; tot-=bo[num];//cout<<bo[num]<<endl; //cout<<bo[num]<<endl; b-=bo[num];//cout<<b<<endl; //cout<<tot<<endl; b%=tot;//cout<<b<<endl; if(b==0) b+=tot; //cout<<tot<<endl; num=mp[b+bo[num]]; break; } } out(num); return 0; }