USACO 2.2.4 [Party Lamps] (lamps)

本文介绍了一种通过有限的操作序列来改变一组灯泡状态的算法。该算法利用16种可能的操作来解决灯泡从初始状态到目标状态的转换问题,并提供了一个具体的Pascal程序实现。
算法:数值,规律,模拟
别人的程序,各种看不懂……
基本思路却是明白了,就是最多有16种变化方案:1,2,3,4,1-2,1-3,1-4,2-3,2-4,3-4,1-2-3,1-2-4,1-3-4,2-3-4,1-2-3-4,1-1-1-1(也可以是别的,总之就是不做任何操作。)

如果总长度大于6,就可以转化成长度为6的数列,原因是第4种操作顺序是1,4,7,10,13,16……,即1和7类似,4和10类似,因此可以转化。

{
ID:1011mashuo
PROG:lamps
LANG:PASCAL
}
program lamps;

const
  lam:array [1..8,1..6]of longint=((0,0,0,0,0,0),(0,0,1,1,1,0),(0,1,0,1,0,1),(0,1,1,0,1,1),(1,0,0,1,0,0),(1,0,1,0,1,0),(1,1,0,0,0,1),(1,1,1,1,1,1));
  tim1:array [1..8] of longint=(1,2,1,1,2,1,2,0);
  tim2:array [1..8] of longint=(2,3,2,4,3,2,3,3);

var
  n,c:longint;
  ka,gu:array [1..6] of boolean;
  can:array [1..8] of boolean;

procedure indata;
var
  i,t:longint;
begin
  fillchar(ka,sizeof(ka),0);
  fillchar(gu,sizeof(gu),0);
  fillchar(can,sizeof(can),1);
  readln(n,c);
  while not eoln do
    begin
      read(t);
      if (t<0) then
        begin
          readln;
          break;
        end;
      t:=t mod 6;
      if (t=0) then t:=6;
      ka[t]:=true;
    end;
  while not eoln do
    begin
      read(t);
      if (t<0) then break;
      t:=t mod 6;
      if (t=0) then t:=6;
      gu[t]:=true;
    end;
  for i:=1 to 6 do
    begin
      if (ka[i] and gu[i]) then
        begin
          writeln('IMPOSSIBLE');
          close(input);
          close(output);
          halt;
        end;
    end;
end;

procedure main;
var
  i,j:longint;
begin
  for i:=1 to 7 do
    begin
      if ((c<tim1[i]) and (c<tim2[i])) then can[i]:=false;
      if can[i] then
        begin
          for j:=1 to 6 do
            begin
              if (ka[j] and (lam[i,j]=0)) then
                begin
                  can[i]:=false;
                  break;
                end;
              if (gu[j] and (lam[i,j]=1)) then
                begin
                  can[i]:=false;
                  break;
                end;
            end;
        end;
    end;
  for i:=1 to 6 do
    begin
      if (ka[i] and (lam[8,i]=0)) then
        begin
          can[8]:=false;
          break;
        end;
      if (gu[i] and (lam[8,i]=1)) then
        begin
          can[8]:=false;
          break;
        end;
    end;
end;

procedure outdata;
var
  i,j,t:longint;
  wo:boolean;
begin
  wo:=true;
  for i:=1 to 8 do
    begin
      if can[i] then
        begin
          t:=0;
          for j:=1 to n do
            begin
              inc(t);
              if (t=7) then t:=1;
              write(lam[i,t]);
            end;
          writeln;
          wo:=false;
        end;
    end;
  if wo then writeln('IMPOSSIBLE');
end;

begin
  assign(input,'lamps.in'); reset(input);
  assign(output,'lamps.out'); rewrite(output);
  
  indata;
  main;
  outdata;
  
  close(input); close(output);
end.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值