pku 1176 Party Lamps

这道题题意是:
有N盏灯,每个灯有两个状态:开、关。有4个按钮,第一个按钮使得所有灯改变状态,第二个按钮使得奇数号灯改变状态,第三个按钮使得偶数号灯改变状态,第四个按钮使得3K+1号灯改变状态。
开始所有灯都是亮着的,给出操作次数,最后亮着的灯和灭了的灯,求最后所有可能的状态。
这题可以用模二方程组来表示。设a、b、c、d分别为第一个、第二个、第三个、第四个按钮按过的次数。count为操作总数,满足:
如第k盏灯亮着
如k%2==1&&(k-1)%3==0,则(a+b+d)%2=0
如k%2==1&&(k-1)%3==1,则(a+b)%2=0
如k%2==0&&(k-1)%3==0,则(a+c+d)%2=0
如k%2==0&&(k-1)%3==1,则(a+c)%2=0
如第k盏灯灭着
如k%2==1&&(k-1)%3==0,则(a+b+d)%2=1
如k%2==1&&(k-1)%3==1,则(a+b)%2=1
如k%2==0&&(k-1)%3==0,则(a+c+d)%2=1
如k%2==0&&(k-1)%3==1,则(a+c)%2=1

开始想用高斯消元来处理这个方程组,后来一看变量只有4个。。而且是模二关系下的方程组,直接枚举即可,总状态数不过16种。然后构造解并hash判重即可。

代码如下:
 1import java.io.*;
 2import java.util.*;
 3public class Main {
 4
 5    /**
 6     * @param args
 7     */

 8    static int n=0,co=0,flag[]=new int [10];
 9    static char res[];
10    static TreeSet<String> ans=new TreeSet<String>();
11    static void makeans(int a,int b,int c,int d,int pos)
12    {
13        if(pos>n)
14        {
15            ans.add(new String(res));
16        }

17        else
18        {
19            if(pos%2==1)
20                if((pos-1)%3==0)
21                    res[pos-1]=(char)((a+b+d+1)%2+48);
22                else
23                    res[pos-1]=(char)((a+b+1)%2+48);
24            else
25                if((pos-1)%3==0)
26                    res[pos-1]=(char)((a+c+d+1)%2+48);
27                else
28                    res[pos-1]=(char)((a+c+1)%2+48);
29            makeans(a,b,c,d,pos+1);
30        }

31    }

32    public static void main(String[] args) throws IOException{
33        StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
34        in.nextToken();
35        n=(int)in.nval;;
36        in.nextToken();
37        co=(int)in.nval;
38        Arrays.fill(flag,-1);
39        flag[0]=co&1;
40        res=new char[n];
41        while(true)
42        {
43            in.nextToken();
44            if((int)in.nval==-1break;
45            int t=(int)in.nval;
46            if((t&1)==1)
47                if((t-1)%3==0)
48                    flag[3]=0;
49                else
50                    flag[1]=0;
51            else
52                if((t-1)%3==0)
53                    flag[4]=0;
54                else
55                    flag[2]=0;
56        }

57        while(true)
58        {
59            in.nextToken();
60            if((int)in.nval==-1break;
61            int t=(int)in.nval;
62            if((t&1)==1)
63                if((t-1)%3==0)
64                    flag[3]=1;
65                else
66                    flag[1]=1;
67            else
68                if((t-1)%3==0)
69                    flag[4]=1;
70                else
71                    flag[2]=1;
72        }

73        for(int a=0;a<=1;a++)
74            for(int b=0;b<=1;b++)
75                for(int c=0;c<=1;c++)
76                    for(int d=0;d<=1;d++)
77                    {
78                        if(a+b+c+d>co) continue;
79                        if(((a+b+c+d)&1)!=flag[0]) continue;
80                        if(flag[1]!=-1&&((a+b)&1)!=flag[1]) continue;
81                        if(flag[2]!=-1&&((a+c)&1)!=flag[2]) continue;
82                        if(flag[3]!=-1&&((a+b+d)&1)!=flag[3]) continue;
83                        if(flag[4]!=-1&&((a+c+d)&1)!=flag[4]) continue;
84                        makeans(a,b,c,d,1);
85                    }

86        for(String p:ans)
87           System.out.println(p);
88    }

89
90}

91

posted on 2010-10-19 14:17 yzhw 阅读(199) 评论(0)  编辑 收藏 引用 所属分类: numberic


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜