USACO 2.2.4 Party Lamps 题解

【算法】模拟  【难度】★★★☆☆


 关键在于题目分析。此题要求按下C次后符合要求的灯的所有情况。按题意,0<=C<=10000,如果直接枚举所有的情况并判断显然会超时。注意分析题目可知:

1、任意一个按钮按下两次相当于一次都没按。利用这一点可以解决所有C>4的情况。由于只有4个按钮,所以C>4时必然至少有一个按钮被按下两次,故所有的情况可归为以下15种:
1   2   3   4   12  13  14  23  24  34  123 124 134 234 一个都没按(c==0)
2、按下2并按下3相当于按下1。同样的,按下1和2相当于3,按下1和3相当于2。所以以上15种情况可以归为:
C==0        一个都没按
C==1    1   2   3   4
C>=2    1   2   3   4   14  24  34 
按此模拟并判断即可。

【收获】对于看起来情况较多、比较复杂的题,要注意分析题意。另外要注意审题,不要遗漏例外的情况。

View Code
  1 /*
2 ID: wsc5001
3 LANG: C
4 TASK: lamps
5 */
6 int n,sn,c;
7 int a,b;
8 int ans[500][103],ai;
9 int op[101],cs[101];
10 #include <stdio.h>
11 #include <stdlib.h>
12 void printans(int coin)
13 {
14 int i,ct=0;;
15 while (1)
16 {
17 for (i=0;i<n;i++)
18 {
19 printf("%d",((coin>>(n-i-1))&1));
20 ct++;
21 if (ct==sn)
22 {printf("\n");return;}
23 }
24 }
25 }
26 void checkit()
27 {
28 int i,j,k;
29 for (k=0;k<ai;k++)
30 {
31 for (i=0;i<a;i++)
32 {
33 if (ans[k][102]!=-1&&ans[k][op[i]]!=1)
34 {ans[k][102]=999;break;}
35 }
36 }
37 for (k=0;k<ai;k++)
38 {
39 for (i=0;i<b;i++)
40 {
41 if (ans[k][102]!=-1&&ans[k][cs[i]]!=0)
42 {ans[k][102]=999;break;}
43 }
44 }
45 }
46 int main()
47 {
48 freopen("lamps.in","r",stdin);
49 freopen("lamps.out","w",stdout);
50 int i,j,k,temp,e,flag;
51
52 scanf("%d%d",&n,&c);
53 //input
54
55 i=0;
56 scanf("%d",&temp);
57 while(temp!=-1)
58 {op[i]=temp;i++;scanf("%d",&temp);}
59 a=i;
60 //system("pause");
61 i=0;
62 scanf("%d",&temp);
63 while(temp!=-1)
64 {cs[i]=temp;i++;scanf("%d",&temp);}
65 b=i;
66
67
68
69
70 for (i=1;i<=n;i++)
71 ans[i][102]=0;
72 /*ans[1]=438;
73 ans[2]=682;
74 ai=3;
75 checkit();
76 printf("%d %d %d",ans[0],ans[1],ans[2]);*/
77
78 if(c==0)
79 {
80 for (i=1;i<=n;i++)
81 ans[0][i]=1;
82 ai=1;
83 checkit();
84 }
85
86 if(c==1)
87 {
88 //ans[0]=0;
89 //ji
90 for (i=1;i<=n;i++)
91 {
92 if ((i&1)==1)
93 ans[1][i]=0;
94 else
95 ans[1][i]=1;
96
97 }
98 //ou
99 for (i=1;i<=n;i++)
100 {
101 if ((i&1)==0)
102 ans[3][i]=0;
103 else
104 ans[3][i]=1;
105 }
106 //ans[0]=0;
107 for (i=1;i<=n;i++)
108 {
109 if ((i%3)==1)
110 ans[2][i]=0;
111 else
112 ans[2][i]=1;
113 }
114 ai=4;
115 //printans(ans[0]);
116 //printf("****%d %d %d %d****\n",ans[1],ans[2],ans[3],ans[0]);
117
118 checkit();
119 }
120
121 if (c>=2)
122 {
123 for (i=1;i<=n;i++)
124 ans[7][i]=1;
125 for (i=1;i<=n;i++)
126 ans[0][i]=0;
127 //2
128 for (i=1;i<=n;i++)
129 {
130 if ((i&1)==1)
131 ans[2][i]=0;
132 else
133 ans[2][i]=1;
134
135 }
136 //3
137 for (i=1;i<=n;i++)
138 {
139 if ((i&1)==0)
140 ans[5][i]=0;
141 else
142 ans[5][i]=1;
143 }
144 //4;
145 for (i=1;i<=n;i++)
146 {
147 if ((i%3)==1)
148 ans[3][i]=0;
149 else
150 ans[3][i]=1;
151 }
152 // 1 4
153 for (i=1;i<=n;i++)
154 {
155 if ((i%3)==1)
156 ans[4][i]=1;
157 else
158 ans[4][i]=0;
159 }
160 //2 4
161 for (i=1;i<=n;i++)
162 {
163 if (ans[2][i]==0)
164 {
165 if (ans[3][i]==1)
166 ans[6][i]=0;
167 else
168 ans[6][i]=1;
169 }
170 else
171 {
172 if (ans[3][i]==1)
173 ans[6][i]=1;
174 else
175 ans[6][i]=0;
176 }
177 }
178 // 34
179 for (i=1;i<=n;i++)
180 {
181 if (ans[5][i]==0)
182 {
183 if (ans[3][i]==1)
184 ans[1][i]=0;
185 else
186 ans[1][i]=1;
187 }
188 else
189 {
190 if (ans[3][i]==1)
191 ans[1][i]=1;
192 else
193 ans[1][i]=0;
194 }
195 }
196 ai=8;
197
198 checkit();
199 }
200
201 //quicksort(0,ai-1);
202 e=0;
203 for (i=0;i<ai;i++)
204 {
205 if (ans[i][102]!=999)
206 {
207 for (j=1;j<=n;j++)
208 printf("%d",ans[i][j]);
209 printf("\n");
210 e=1;
211 }
212 //printf("%d\n",ans[i]);
213 //{printans(ans[i]);e=1;}
214 }
215 if (e==0)
216 printf("IMPOSSIBLE\n");
217 //system("pause");
218 fclose(stdin);
219 fclose(stdout);
220 }



posted @ 2012-03-25 19:54  wsc500  阅读(262)  评论(0编辑  收藏  举报