USACO 2.2.4 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 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:
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 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)
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.

题目大意就是给出灯的个数,和对灯的操作规则,和经过C步操作后亮着的部分灯和熄灭的部分灯,求灯最后的可能情况,如果没有输出`IMPOSSIBLE'

  • 按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄灭,本来是关着的灯被点亮。
  • 按钮2:当按下此按钮,将改变所有奇数号的灯。
  • 按钮3:当按下此按钮,将改变所有偶数号的灯。
  • 按钮4:当按下此按钮,将改变所有序号是3*K+1(K>=0)的灯。例如:1,4,7...

注意到当每对一个操作实施两次和没实施效果一样,故可将大于4的C减小到3或4;

然后从开始进行搜索没一盏灯进行一步操作后的可能情况,知道进行了C步操作,如果满足题目条件则保存数据再搜索下一组情况

/* 

ID:shiryuw1 

PROG:lamps 

LANG:C++ 

*/ 

#include<iostream> 

#include<cstdlib> 

#include<cstdio> 

#include<cstring> 

#include<algorithm> 

#include<cmath> 

using namespace std; 

int op[105]; 

int cl[105]; 

int n; 

int c; 

int clk=0; 

int opk=0; 

bool found=false; 

struct prog{ 

    int a1; 

    int a2; 

    int a3; 

    int a4; 

    bool str[105]; 

}; 

prog ans[10000]; 

int p=0; 

bool istrue(bool* lap) 

{ 

    int i; 

    for(i=0;i<opk;i++) 

    { 

        if(lap[op[i]-1]!=true) 

            return false; 

    } 

    for(i=0;i<clk;i++) 

    { 

        if(lap[cl[i]-1]!=false) 

            return false; 

    } 

    return true; 

} 

void change(bool* lap,int k) 

{ 

    int st=0; 

    int ad=k; 

    if(k==4) 

    { 

        st=1; 

        ad=2; 

    } 

    int i; 

    for(i=st;i<n;i+=ad) 

        lap[i]=!lap[i]; 

} 

void DFS(bool *lap,int k) 

{ 

    int i,j; 

    if(k/2==c/2) 

    { 

        if(istrue(lap)) 

        { 

            

            for(j=0;j<n;j++) 

                ans[p].str[j]=lap[j]; 

            for(j=0;j<25;j++) 

            { 

                ans[p].a1=ans[p].a1*2+ans[p].str[j];



                

            }



            for(j=25;j<50;j++) 

            {



                ans[p].a2=ans[p].a2*2+ans[p].str[j]; 

                

            }



            for(j=50;j<75;j++) 

            { 

                ans[p].a3=ans[p].a3*2+ans[p].str[j]; 

                

            }



            for(j=75;j<100;j++) 

            { 

                ans[p].a4=ans[p].a4*2+ans[p].str[j]; 

            } 

            p++; 

            found=true; 

        } 

        return ; 

    } 

    for(i=1;i<=4;i++) 

    { 

    

        bool tmp[105];





        for(j=0;j<n;j++) 

        { 

            tmp[j]=lap[j]; 

        } 

        change(tmp,i); 

        DFS(tmp,k+1); 

    } 

} 

int cmp(const void *a,const void *b) 

{ 

    if((*(prog *)a).a1!=(*(prog *)b).a1) 

        return (*(prog *)a).a1-(*(prog *)b).a1; 

    if((*(prog *)a).a2!=(*(prog *)b).a2) 

        return (*(prog *)a).a2-(*(prog *)b).a2; 

    if((*(prog *)a).a3!=(*(prog *)b).a3) 

        return (*(prog *)a).a3-(*(prog *)b).a3; 

    return (*(prog *)a).a4-(*(prog *)b).a4;



} 

int main() 

{



    memset(ans,0,sizeof(ans)); 

    bool lap[105]; 

    freopen("lamps.in","r",stdin); 

    freopen("lamps.out","w",stdout); 

    memset(lap,true,sizeof(lap)); 

    cin>>n; 

    cin>>c; 

    while(1) 

    { 

        cin>>op[opk]; 

        

        if(op[opk]==-1) 

            break; 

        opk++; 

    } 

    while(1) 

    { 

        cin>>cl[clk]; 

        

        if(cl[clk]==-1) 

            break; 

        clk++; 

    } 

    if(c>4) 

    { 

        if(c%2) 

            c=3; 

        else 

            c=4; 

    } 

    DFS(lap,0); 

    int i,j; 

    if(!found) 

        cout<<"IMPOSSIBLE"<<endl; 

    else 

    { 

        qsort(ans,p,sizeof(ans[0]),cmp); 

        for(i=0;i<p;i++) 

        { 

            if(i&&ans[i].a1==ans[i-1].a1&&ans[i].a2==ans[i-1].a2&&ans[i].a3==ans[i-1].a3&&ans[i].a4==ans[i-1].a4) 

                continue; 

            for(j=0;j<n;j++) 

            { 

                

                cout<<ans[i].str[j]; 

            } 

            cout<<endl; 

        } 

    } 

    return 0; 

}

你可能感兴趣的:(USACO)