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 );
}

你可能感兴趣的:(USACO)