列表

详情


NC20489. [ZJOI2009]硬币游戏

描述

Orez很喜欢玩游戏,他最近发明了一款硬币游戏。他在桌子的边缘上划分出2*n个位置并按顺时针把它们标号为1,2,……,2n,然后把n个硬币放在标号为奇数的位置上。
接下来每次按如下操作:
在任意两个硬币之间放上一个硬币,然后将原来的硬币拿走;
所放硬币的正反面由它两边的两个硬币决定,若两个硬币均为正面朝上或反面朝上,则所放硬币为正面朝上,否则为反面朝上。 
那么操作T次之后桌子边缘上硬币的情况会是怎样的呢?

输入描述

文件的第一行包含两个整数n和T。 
接下的一行包含n个整数,表示最开始桌面边缘的硬币摆放情况,第i个整数ai表示第i个硬币摆放在2*i-1个位置上,ai=1表示正面朝上,ai=2表示反面朝上。

输出描述

文件仅包含一行,为2n个整数,其中第i个整数bi桌面边缘的第i个位置上硬币的情况,bi=1表示正面朝上,bi=2表示反面朝上,bi=0表示没有硬币。

示例1

输入:

10 5
2 2 2 1 1 1 1 1 1 2

输出:

0 1 0 1 0 1 0 1 0 2 0 1 0 2 0 1 0 1 0 1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 80ms, 内存消耗: 1272K, 提交时间: 2020-02-14 18:38:44

#include<iostream>
using namespace std;
int n,num[100000],nu[100000];
void f(long long k)
{
	for(int i=0;i<n;i++)
	nu[i]=(num[i]+num[(i+k)%n])%2+1;
	for(int i=0;i<n;i++) num[i]=nu[i];
}
void out(long long tt)
{
	for(int i=0;i<n;i++)
	{
		if(tt%2) cout<<"0 ";
		cout<<num[((i-tt/2)%n+n)%n];
		if(tt%2==0) cout<<" 0";
		cout<<((n-i-1)?" ":"\n");
	}
}
int main()
{
	long long t,tt;
	cin>>n>>t;
	for(int i=0;i<n;i++) cin>>num[i];
	tt=t;
	while(t)
	{
		f(t&-t);
		t&=t-1;
	}
	out(tt);
	return 0;
}

上一题