[USACO 2.2.4] Party Lamps

来源:互联网 发布:mac上好用的图片软件 编辑:程序博客网 时间:2024/04/30 00:30

[题目描述]

Party Lamps

派对灯

IOI98

在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

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

第一行:N。第二行:C最后显示的数值。第三行:最后亮着的灯,用一个空格分开,以-1为结束。第四行: 最后关着的灯,用一个空格分开,以-1为结束。

SAMPLE INPUT (file lamps.in)

10
1
-1
7 -1

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

OUTPUT FORMAT

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

SAMPLE OUTPUT (file lamps.out)

0000000000
0101010101
0110110110

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

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

[解题思路]
第一下看题的时候真不知道题目说的是什么...
再翻译下题目大意吧,就是有4种操作,希望通过C次操作,使最后灯的开关符合输入要求。
是否发现每个操作只有操作奇数次才有用,并且整个灯串是有长度为6的循环节的。
也就是说最多也只会操作4次,并且灯1与灯7亮暗相同,灯2与灯8相同......于是记录前6个灯的状态,枚举操作+检验即可。
代码写得比较烦,搞了将近1个多小时...坑爹的是,并不一定要操作C次,是0~C次。

[Code]
{ID: zane2951PROG: lampsLANG: PASCAL}program lamps;const   modify:array[1..4] of longint=(63,42,21,36);var   ss:string;   s:array[0..71] of string;   v:array[0..71] of boolean;   onn,off:array[0..7] of boolean;   c,n,top,i,x,ce:longint;//---------check-----------function check(x:longint):boolean;var   ce,len:longint;begin   ss:='';   while x>0 do      begin         ce:=x and 1;         if ce>0 then ss:='1'+ss else ss:='0'+ss;         x:=x>>1;      end;   len:=length(ss);   while len<6 do begin ss:='0'+ss; inc(len); end;   for ce:=1 to 6 do if onn[ce] then if ss[ce]<>'1' then exit(false);   for ce:=1 to 6 do if off[ce] then if ss[ce]<>'0' then exit(false);   exit(true);end;//----------run------------procedure run(dp,up,ti,now:longint);begin   if ti>up then exit;   if dp>4 then      begin         if check(now) then            if not v[now] then begin v[now]:=true; inc(top); s[top]:=ss; end;         exit;      end;   if check(now) then      if not v[now] then begin v[now]:=true; inc(top); s[top]:=ss; end;   run(dp+1,up,ti+1,now xor modify[dp]);   run(dp+1,up,ti,now);end;//-----------qs------------procedure qs(ss,tt:longint);var   i,j:longint;   ce,tmp:string;begin   i:=ss; j:=tt; ce:=s[(i+j)>>1];   repeat      while s[i]<ce do inc(i);      while s[j]>ce do dec(j);      if i<=j then         begin            tmp:=s[i]; s[i]:=s[j]; s[j]:=tmp;            inc(i); dec(j);         end;   until i>j;   if ss<j then qs(ss,j); if i<tt then qs(i,tt);end;//----------main-----------begin   assign(input,'lamps.in'); reset(input);   assign(output,'lamps.out'); rewrite(output);   readln(n);   readln(c);   while true do      begin read(x); if x<0 then break; onn[((x-1) mod 6)+1]:=true; end;   while true do      begin read(x); if x<0 then break; off[((x-1) mod 6)+1]:=true; end;   if c>4 then c:=4; top:=0; ce:=1<<6-1;   run(1,c,0,ce);   qs(1,top);   if top>0 then      for i:=1 to top do         begin            for ce:=1 to (n div 6) do write(s[i]);            ce:=n mod 6;            for x:=1 to ce-1 do write(s[i,x]);            writeln(s[i,ce]);         end      else writeln('IMPOSSIBLE');   close(input); close(output);end.


原创粉丝点击