USACO 2.2 Party Lamps

类型:枚举

描述:

 Party Lamps
IOI 98

To brighten up the gala dinner of the IOI'98 we have a set of N(10 <= N <= 100) colored lamps numbered from 1 to N.

The lamps are connected to four buttons:

 

  • Button 1: When this button is pressed, all the lamps change their state: those that are ON are turned OFF and those that are OFF are turned ON.
  • Button 2: Changes the state of all the odd numbered lamps.
  • Button 3: Changes the state of all the even numbered lamps.
  • Button 4: Changes the state of the lamps whose number is of the form3xK+1 (with K>=0), i.e., 1,4,7,...

A counter C records the total number of button presses.

When the party starts, all the lamps are ON and the counter Cis set to zero.

You are given the value of counter C (0 <= C <= 10000) and thefinal state of some of the lamps after some operations have been executed.Write a program to determine all the possible final configurations ofthe N lamps that are consistent with the given information, withoutrepetitions.

PROGRAM NAME: lamps

INPUT FORMAT

No lamp will be listed twice in the input.

Line 1: N
Line 2: Final value of C
Line 3: Some lamp numbers ON in the final configuration, separated by one space and terminated by the integer -1.
Line 4: Some lamp numbers OFF in the final configuration, separated by one space and terminated by the integer -1.

SAMPLE INPUT (file lamps.in)

10
1
-1
7 -1

In this case, there are 10 lamps and only one button has been pressed.Lamp 7 is OFF in the final configuration.

OUTPUT FORMAT

Lines with all the possible final configurations (without repetitions)of all the lamps. Each line has N characters, where the first characterrepresents the state of lamp 1 and the last character represents thestate of lamp N. A 0 (zero) stands for a lamp that is OFF, and a 1(one) stands for a lamp that is ON. The lines must be ordered fromleast to largest (as binary numbers).

If there are no possible configurations, output a single line withthe single word `IMPOSSIBLE'

SAMPLE OUTPUT (file lamps.out)

0000000000
0101010101
0110110110

In this case, there are three possible final configurations:

  • All lamps are OFF
  • Lamps 1, 4, 7, 10 are OFF and lamps 2, 3, 5, 6, 8, 9 are ON.
  • Lamps 1, 3, 5, 7, 9 are OFF and lamps 2, 4, 6, 8, 10 are ON.

 

思路:1.有4种操作,操作的顺序与结果无关,两次同样的操作=无操作,于是可以枚举24种操作;2.进一步的优化是,灯的状态可以压缩成6bit。

ps:请先自己实现,再参考标程。

 

标程
#include <stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<assert.h>

#define MAXLAMP 6
#define LAMPMASK ((1<<MAXLAMP)-1)

int nlamp;
int nswitch;
int ison;
int known;

int poss[1<<MAXLAMP];

int flip[4] = {
LAMPMASK,
/* flip all lights */
LAMPMASK
& 0xAA, /* flip odd lights */
LAMPMASK
& 0x55, /* flip even lights */
LAMPMASK
& ((1<<(MAXLAMP-1))|(1<<(MAXLAMP-4))) /* lights 1, 4 */
};

/*
* Starting with current light state ``lights'', flip exactly n switches
* with number >= i.
*/
void
search(
int lights, int i, int n)
{
if(n == 0) {
if((lights & known) == ison)
poss[lights]
= 1;
return;
}

for(; i<4; i++)
search(lights
^ flip[i], i+1, n-1);
}

void
printseq(FILE
*fout, int lights)
{
int i;
char s[100+1];

for(i=0; i<nlamp; i++)
s[i]
= (lights & (1<<(MAXLAMP-1 - i%MAXLAMP))) ? '1' : '0';
s[nlamp]
= '\0';
fprintf(fout,
"%s\n", s);
}

void
main(
void)
{
FILE
*fin, *fout;
int a, i, impossible;

fin
= fopen("lamps.in", "r");
fout
= fopen("lamps.out", "w");
assert(fin
!= NULL && fout != NULL);

fscanf(fin,
"%d %d", &nlamp, &nswitch);

for(;;) {
fscanf(fin,
"%d", &a);
if(a == -1)
break;
a
= MAXLAMP-1 - (a-1) % MAXLAMP;
ison
|= 1<<a;
known
|= 1<<a;
}

for(;;) {
fscanf(fin,
"%d", &a);
if(a == -1)
break;
a
= MAXLAMP-1 - (a-1) % MAXLAMP;
assert((ison
& (1<<a)) == 0);
known
|= 1<<a;
}

if(nswitch > 4)
if(nswitch%2 == 0)
nswitch
= 4;
else
nswitch
= 3;

for(; nswitch >= 0; nswitch -= 2)
search(LAMPMASK,
0, nswitch);

impossible
= 1;
for(i=0; i<(1<<MAXLAMP); i++) {
if(poss[i]) {
printseq(fout, i);
impossible
= 0;
}
}
if(impossible)
fprintf(fout,
"IMPOSSIBLE\n");

exit(
0);
}
posted @ 2010-07-30 11:27  superbin  阅读(635)  评论(0编辑  收藏  举报