ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1960. 闪烁

2022-01-29 14:34:53  阅读:152  来源: 互联网

标签:状态 return int 1960 灯泡 时刻 闪烁 define


农夫约翰对牛棚里昏暗的灯光感到不满,刚刚安装了一个新吊灯。

新吊灯由 \(N\) 个灯泡组成,这 \(N\) 个灯泡围成一圈,编号为 \(0∼N−1\)。

奶牛对这个新吊灯非常着迷,并且喜欢玩以下游戏:

对于第 \(i\) 个灯泡,如果在 \(T−1\) 时刻,它左侧的灯泡(当 \(i>0\) 时,为第 \(i−1\) 个灯泡;当 \(i=0\) 时,为第 \(N−1\) 个灯泡)是开着,那么在 \(T\) 时刻,就切换这个灯泡的状态。

这个游戏将持续 \(B\) 单位时间。

给定灯泡的初始状态,请确定在 \(B\) 单位时间后,它们的最终状态。

输入格式

第一行包含两个整数 \(N\) 和 \(B\)。

接下来 \(N\) 行,按顺序描述每个灯泡的初始状态,每行包含一个整数 \(1\) (表示开)或 \(0\)(表示关)。

输出格式

共 \(N\) 行,按顺序每行输出一个灯泡的最终状态。

数据范围

\(3≤N≤16\),
$1≤B≤10^{15}

输入样例:

5 6
1
0
0
0
0

输出样例:

1
1
1
0
1

样例解释

灯泡状态如下:

时刻 T=0: 1 0 0 0 0
时刻 T=1: 1 1 0 0 0
时刻 T=2: 1 0 1 0 0
时刻 T=3: 1 1 1 1 0
时刻 T=4: 1 0 0 0 1
时刻 T=5: 0 1 0 0 1
时刻 T=6: 1 1 1 0 1

解题思路

状态压缩,抽屉原理

将二进制状态压缩为一个十进制,可以发现:最多共有 \(2^n\) 种状态,其中 \(n\) 的值较小,每次灯泡状态改变时即每一位跟前一位异或得到新状态,由抽屉原理,最多改变状态 \(2^n\) 次,会进入旧状态,此时便形成一个环,找出环上节点个数即剩余改变状态次数的周期,求余数即为在该环中还需改变状态的次数

  • 时间复杂度:\(O(2^{n+1})\)

代码

// Problem: 闪烁
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/1962/
// Memory Limit: 64 MB
// Time Limit: 1000 ms

// %%%Skyqwq
#include <bits/stdc++.h>

#define pb push_back
#define fi first
#define se second
#define mp make_pair
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

int n;
LL b;
int cnt[70000];
inline int update(int state)
{
	int res=0;
	for(int i=0;i<n;i++)
		res|=((state>>i&1)^(state>>((i+n-1)%n)&1))<<i;
	return res;
}
int main()
{
	scanf("%d%lld",&n,&b);
	int state=0;
	for(int i=0;i<n;i++)
	{
		int x;
		scanf("%d",&x);
		state|=x<<i;	
	}
	cnt[state]=1;
	for(int i=2;i<=b+1;i++)
	{
		state=update(state);
		if(cnt[state])
		{
			int cycle=i-cnt[state];
			for(int j=0;j<(b+1-i)%cycle;j++)
				state=update(state);
			break;
		}
		else
			cnt[state]=i;
	}
	for(int i=0;i<n;i++)printf("%d\n",state>>i&1);
	return 0;
}

标签:状态,return,int,1960,灯泡,时刻,闪烁,define
来源: https://www.cnblogs.com/zyyun/p/15855002.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有