Party Lamps

来源:互联网 发布:你可能需要与该网络isp 编辑:程序博客网 时间:2024/04/30 05:48
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 form 3xK+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 C is set to zero.

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

PROGRAM NAME: lamps

INPUT FORMAT

No lamp will be listed twice in the input.

Line 1:NLine 2:Final value of CLine 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)

101-17 -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 character represents the state of lamp 1 and the last character represents the state 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 from least to largest (as binary numbers).

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

SAMPLE OUTPUT (file lamps.out)

000000000001010101010110110110
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.





题解:
   c的值是我们必须考虑的,应为它直接影响我们的枚举,从中有规律可找;
  我是这样想的:

      如果c是偶数,那么对这四种按键,可分为挑选其中4个、2个、0个;
    如果c是奇数,那么对这四种按键,可分为挑选其中1个、3个;

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
int f[20][101];
int ll[20][4];
int w[101];
int a[101],b[101];
inline void tt(int,int);
inline int ss(int,int);
inline void sort(int,int);
inline bool ok();
int h=0,n,c,l=0,r=0;
int main()
{
freopen("lamps.in","r",stdin);
    freopen("lamps.out","w",stdout);
scanf("%d",&n);
scanf("%d",&c);
int p;
scanf("%d",&p);
while (p!=-1) {l++;a[l]=p;scanf("%d",&p);}
scanf("%d",&p);
while (p!=-1) {r++;b[r]=p;scanf("%d",&p);}
for (int i=1;i<=n;i++) w[i]=1;
if (c&1)
{
if (c>=1) tt(1,1);
if (c>=3) tt(3,1);
    }else 
    {
if (ok()){h++;for (int u=1;u<=n;u++) f[h][u]=w[u];}
if (c>=2) tt(2,1);
if (c>=4) tt(4,1);
    }
  memset(ll,0,sizeof(ll));
  if (h>0) 
  {
   for (int i=1;i<=h;i++) 
   {
  ll[i][1]=ss(1,i);
  ll[i][2]=ss(30,i);
  ll[i][3]=ss(60,i);
   }
   sort(1,h);
   for (int i=1;i<=h;i++) 
   {
   for (int j=1;j<=n;j++) printf("%d",f[i][j]);
   std::cout<<'\n';
   }
  }
  else printf("%s\n","IMPOSSIBLE");
  return 0;  
}


int ss(int x,int y)//二进制值;
{
  int i=0,p=0;
  while ((i<30)&&(x+i<n))
  {
p=p*2+f[y][x+i];
i++;
  }
 return p;
}


bool ok()//判断;
{
 for (int i=1;i<=l;i++)
  if (1!=w[a[i]]) return false;
 for (int i=1;i<=r;i++)
  if (0!=w[b[i]]) return false;
 return true;
}


void sort(int x,int y)//排序;
{
int i=x,j=y,k=ll[(x+y)/2][1],kk=ll[(x+y)/2][2],kkk=ll[(x+y)/2][3];
do
{
while ((ll[j][1]>k)||((ll[j][1]==k)&&(ll[j][2]>kk))||((ll[j][1]==k)&&(ll[j][2]==kk)&&(ll[j][3]>kkk))) j--;
while ((ll[i][1]<k)||((ll[i][1]==k)&&(ll[i][2]<kk))||((ll[i][1]==k)&&(ll[i][2]==kk)&&(ll[i][3]<kkk))) i++;
if (i<=j)
{
for (int bb=1;bb<=n;bb++)
{
int t=f[i][bb];
f[i][bb]=f[j][bb];
f[j][bb]=t;
}
int t;
t=ll[i][1];ll[i][1]=ll[j][1];ll[j][1]=t;
t=ll[i][2];ll[i][2]=ll[j][2];ll[j][2]=t;
t=ll[i][3];ll[i][3]=ll[j][3];ll[j][3]=t;
i++;j--;
   }
    }while (i<=j);
    if (i<y) sort(i,y);
    if (j>x) sort(x,j);
}


void tt(int x,int y)//枚举;
{
if (x==0)
{
  if (ok())
  {
h++;
for (int bb=1;bb<=n;f[h][bb]=w[bb],bb++);
  }
  return;
}
for (int i=y;i<=4;i++)
{
       switch (i)
 {
case 1:{for (int j=1;j<=n;j++) w[j]=1-w[j];tt(x-1,i+1);for (int j=1;j<=n;j++) w[j]=1-w[j];}
break;
case 2:{for (int j=0;j<=n/2;j++) w[j*2+1]=1-w[j*2+1];tt(x-1,i+1);for (int j=0;j<=n/2;j++) w[j*2+1]=1-w[j*2+1];}
break;
case 3:{for (int j=1;j<=n/2;j++) w[j*2]=1-w[j*2];tt(x-1,i+1);for (int j=1;j<=n/2;j++) w[j*2]=1-w[j*2];}
break;
case 4:{for (int j=0;j<=(n-1)/3+1;j++) w[j*3+1]=1-w[j*3+1];tt(x-1,i+1);for (int j=0;j<=(n-1)/3+1;j++) w[j*3+1]=1-w[j*3+1];}
break;
 }
  }
  return;
}
0 0
原创粉丝点击