永夜初晗凝碧天

本博客现已全部转移到新地址,欲获取更多精彩文章,请访问http://acshiryu.github.io/

导航

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

posted on 2011-07-15 21:01  ACShiryu  阅读(485)  评论(0编辑  收藏  举报