[USACO2.2]Party Lamps派对灯

来源:互联网 发布:远东电缆营销网络 编辑:程序博客网 时间:2024/04/29 18:02

Party Lamps派对灯(IOI98)

目录

 [隐藏] 
  • 1 描述
  • 2 格式
  • 3 SAMPLE INPUT
  • 4 SAMPLE OUTPUT

[编辑]描述

在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码。 这些灯都连接到四个按钮:

按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄灭,本来是关着的灯被点亮。 按钮2:当按下此按钮,将改变所有奇数号的灯。按钮3:当按下此按钮,将改变所有偶数号的灯。按钮4:当按下此按钮,将改变所有序号是3*K+1(K>=0)的灯。例如:1,4,7...

一个计数器C记录按钮被按下的次数。当宴会开始,所有的灯都亮着,此时计数器C为0。

你将得到计数器C(0<=C<=10000)上的数值和经过若干操作后某些灯的状态。写一个程序去找出所有灯最后可能的与所给出信息相符的状态,并且没有重复。

[编辑]格式

PROGRAM NAME: lamps

INPUT FORMAT:

(file lamps.in)

不会有灯会在输入中出现两次。

第一行: N。

第二行: C最后显示的数值。

第三行: 最后亮着的一些灯,用一个空格分开,以-1为结束。

第四行: 最后关着的一些灯,用一个空格分开,以-1为结束。

OUTPUT FORMAT:

(file lamps.out)

每一行是所有灯可能的最后状态(没有重复)。每一行有N个字符,第1个字符表示1号灯,最后一个字符表示N号灯。0表示关闭,1表示亮着。这些行必须从小到大排列(看作是二进制数)。

如果没有可能的状态,则输出一行'IMPOSSIBLE'。

[编辑]SAMPLE INPUT

101-17 -1

在这个样例中,有10盏灯,只有1个按钮被按下。最后7号灯是关着的。

[编辑]SAMPLE OUTPUT

000000000001010101010110110110

在这个样例中,有三种可能的状态:

所有灯都关着

1,4,7,10号灯关着,2,3,5,6,8,9亮着。

1,3,5,7,9号灯关着,2, 4, 6, 8, 10亮着。





【题解】

111111 初始  //一种

000000 ①   //两种
010101 ②  //三种
101010 ③//四种
011011 ④ //五种
101010 ①②=②①=③
010101 ①③=③①=②
100100 ①④=④①  //六种
000000 ②③=①
110001 ②④ //七种

001110 ③④ //八种

一共八种情况,当c>=3时,任何情况下都可以拆分。

例如c=3   ①②③=③③=1111111

同理,c=4可拆分成   ①②③④=③③④=④

所以只要八次改变即可。


/*ID:luojiny1LANG:C++TASK:lamps*/#include<cstdio>#include<cstring>#include<algorithm>const int maxn=100;typedef bool State[maxn];State e,s,f={0};int n,c,id,m=0;struct Vis{State v;bool operator<(const Vis& x){for(int i=0;i<n;i++)if(v[i]<x.v[i])return true;else if(v[i]>x.v[i])return false;return false;}}vis[10];bool ok(State num){for(int i=0;i<n;i++)if(num[i]!=e[i]&&f[i])return false;return true;}void show(State num){for(int i=0;i<n;i++)printf("%d",num[i]);printf("\n");return;}bool pd(State num){for(int i=0;i<m;i++){bool flag=0;for(int j=0;j<n;j++)if(vis[i].v[j]!=num[j]){flag=1;break; }if(flag==0)return false;}return true;}void dfs(){State temp;for(int i=0;i<16;i++){int cnt=0;for(int j=0;j<n;j++)temp[j]=1;if(i&1<<0){cnt++;for(int i=0;i<n;i++)temp[i]=1-temp[i];}if(i&1<<1){cnt++;for(int i=0;i<n;i+=2)temp[i]=1-temp[i];}if(i&1<<2){cnt++;for(int i=1;i<n;i+=2)temp[i]=1-temp[i];}if(i&1<<3){cnt++;for(int i=0;i<n;i++)temp[i*3]=1-temp[i*3];}if(ok(temp)&&pd(temp)&&cnt<=c){for(int i=0;i<n;i++)vis[m].v[i]=temp[i];m++;}}return ;}int main(){freopen("lamps.in","r",stdin);freopen("lamps.out","w",stdout);scanf("%d%d",&n,&c);for(int i=0;i<n;i++)s[i]=e[i]=1;while(scanf("%d",&id)==1&&id!=-1)f[id-1]=1;while(scanf("%d",&id)==1&&id!=-1){e[id-1]=0;f[id-1]=1;}dfs();std::sort(vis,vis+m);for(int i=0;i<m;i++)show(vis[i].v);if(!m)printf("IMPOSSIBLE\n");return 0;}



原创粉丝点击