灯泡

渝渝家里新房子刚刚装了一个华丽的新的枝形吊灯,由 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;
}

 

转载于:https://www.cnblogs.com/000226wrp/p/11339463.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值