灯泡(blink.pas/c/cpp)
题目描述:
渝渝家里新房子刚刚装了一个华丽的新的枝形吊灯,由 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(开)。
输入样例 (blink.in) :
5 6
1
0
0
0
0
输入详情:
总共有 5 个灯泡。 第一个一开始是开的,其他的都是关的。
输出样例(blink.out):
1
1
1
0
1
输出详情:
灯泡的状态如下:
Time T=0: 1 0 0 0 0
Time T=1: 1 1 0 0 0
Time T=2: 1 0 1 0 0
Time T=3: 1 1 1 1 0
Time T=4: 1 0 0 0 1
Time T=5: 0 1 0 0 1
Time T=6: 1 1 1 0 1
这是今天考试的第一题,我以为它很简单(实际上也很简单 ),看了一眼那极致的数据范围,面不改色打了一个暴搜,输入一个极大的数据,它就理所当然地炸了。
然后我就开始了走上今天这条不归路——我瞅了眼n的数据范围3<=N<=16,脑子一抽放弃了电脑,开始人脑计算,算了2小时,就如同昨日一般,其他题没有时间了所以只打了暴力分。
下面是一双年轻的手算出来的规律:
3:3个为一循环
4:b>3的全是0
5:15个为一循环
6:b>1后6个为一循环
7:b>1后7个为一循环
8:b>7的全是0
9:63个为一循环
10:b>1后30个为一循环
11:341个为一循环
12:b>3后12个为一循环
13:819个为一循环
14:b>1后14个为一循环
15:15个为一循环
16:b>15的全是0
下面附上那个长的像打表的代码:
#include<bits/stdc++.h>
using namespace std;
long long n,b,x=1;
int cc[20],mm[20]={0};
int main(){
freopen("blink.in","r",stdin);
freopen("blink.out","w",stdout);
cin>>n>>b;
for(int i=1;i<=n;i++)cin>>cc[i];
if((n==4||n==8||n==16)&&b>=n)b=n;
if(n==3||n==15){
if(b%n==0)b=n;
else b=b%n;
}
if(n==6||n==7||n==14){
if((b-1)%n==0)b=n+1;
else b=(b-1)%n+1;
}
if(n==5){
if(b%15==0)b=15;
else b=b%15;
}
if(n==9){
if(b%63==0)b=63;
else b=b%63;
}
if(n==11){
if(b%341==0)b=341;
else b=b%341;
}
if(n==13){
if(b%819==0)b=819;
else b=b%819;
}
if(n==12){
if((b-3)%n==0)b=n+3;
else b=(b-3)%n+3;
}
if(n==10){
if((b-1)%30==0)b=31;
else b=(b-1)%30+1;
}
while(x<=b){
for(int i=1;i<=n;i++)
if(cc[i]==1&&i+1<=n){
mm[i+1]=1;
}
else
if(cc[i]==1&&i+1>n){
mm[1]=1;
}
for(int i=1;i<=n;i++)
if(mm[i]==1){
mm[i]=0;
if(cc[i]==1)cc[i]=0;
else cc[i]=1;
}
x++;
}
for(int i=1;i<=n;i++)cout<<cc[i]<<endl;
}
衷心祝愿大家不要像我一样!
推荐阅读