USACO Section2.2 Party Lamps 解题报告 【icedream61】
lamps解题报告
------------------------------------------------------------------------------------------------------------------------------------------------
【题目】
N个灯,编号1~N。有4个开关,和C次改变某个开关状态的机会,试问最终所有灯的亮灭情况可能有哪些?
一号开关:改变所有灯的状态。
二号开关:改变所有奇数号灯的状态。
三号开关:改变所有偶数号灯的状态。
四号开关:改变所有3K+1号灯的状态(k=0,1,2,…)。
初始时,所有灯都是亮的。
【输入】
第一行一个数,N。
第二行一个数,C。
后两行,每行有空格分割的一些数,以-1结尾,给出的是此题的“额外限制条件”:
第三行所出现的数,表示编号为这些的灯最终应当处于“亮”的状态,即最后输出时这些位置的数字应当为1;
第四行所出现的数,表示编号为这些的灯最终应当处于“灭”的状态,即最后输出时这些位置的数字应当为0。
【输出】
所有符合题目要求的状态,每行一种状态,用N位的二进制数来表示所有灯的亮灭状态,从最高位到最低位依次是1号到N号灯。
注意,请按照字典序输出。
【数据范围】
N=10~100
C=0~10000
【输入样例】
10
1
-1
7 -1
【输出样例】
0000000000
0101010101
0110110110
------------------------------------------------------------------------------------------------------------------------------------------------
【分析】
如果直接记录所有灯的状态,那么状态数是2的100次方种,明显超空间。
简单观察一下,这道题的灯可以分为6组,分别是除以6模0~5这六组。那么,一号开关就是6组全改变,二、三号开关则是分别改变奇数组和偶数组,四号开关则是仅仅改变3K+1对应的两组。这样一来,所有灯的状态总共只有64种。
继续分析,四个开关,一个初始状态,那么显然我们可以拨动开关0~4次,分别是一个开关都不变直到四个开关都变,就只有这五种情况了。也就是说,C的值只有0~4是有意义的,而一旦比4大,就说明必然灯被拨动了两次,那么可以让C减去2,让这个灯不被这样毫无意义的“玩”,结果显然是一样的。
至此,我们把N变成了6,C变成了0~4,这个模型显然就简单多了。那么,我们只要看看题目最后的限制条件啦~
依旧是映射到1~6号灯所代表的这6组灯上即可,因此这里便可能直接导致题目无解喽~
这就是本题的思路了,余下的就是编程实现细节,不予赘述。
------------------------------------------------------------------------------------------------------------------------------------------------
【总结】
第四次AC,回顾自己这不到一个小时,我还真是“常怀懒惰之心”啊!
两天没做题了,脑子又开始懒了,静不下心来细想,做得很慢错误也多。很简单的题,做的过程中犯了几个细节错误:
1.第一次提交,把代码中main函数里第三个IMPOSSIBLE那种情况给忘了
2.第二次提交,ok函数中if语句&运算的括号没加,导致运算符优先级错误
3.第三次提交,main函数中最后一个循环并未使用kk来保证字典序输出
------------------------------------------------------------------------------------------------------------------------------------------------
【代码】
1 /* 2 ID: icedrea1 3 PROB: lamps 4 LANG: C++ 5 */ 6 7 #include <iostream> 8 #include <fstream> 9 using namespace std; 10 11 // p[101100]: 1,2,5 closed, 3,4,6 openned 12 bool p[64]; // p[k]: can walk to state k 13 bool d[64]; // d[k]: state d is right 14 int r[6],w[4]; 15 int mark[6]; 16 17 int N,C; 18 19 void go(int k,int c) // walk c steps from state k 20 { 21 if(!c) // get a final state 22 { 23 p[k]=true; 24 return; 25 } 26 27 int t; 28 t=k^63; go(t,c-1); 29 t=k^21; go(t,c-1); 30 t=k^42; go(t,c-1); 31 t=k^9; go(t,c-1); 32 } 33 34 bool ok(int k) // return if the state is right 35 { 36 for(int i=0;i!=6;++i) // the lamps in group i 37 if(mark[i]!=-1 && (k&(1<<i))!=(mark[i]<<i)) // the state of lamps in group i is right to mark[i] 38 return false; 39 return true; 40 } 41 42 void print(ostream &out,int k) 43 { 44 bool t[6]; 45 for(int i=0;i!=6;++i) t[i]=k&(1<<i); 46 for(int i=0;i!=N;++i) out<<t[i%6]; 47 out<<endl; 48 } 49 50 int main() 51 { 52 ifstream in("lamps.in"); 53 ofstream out("lamps.out"); 54 55 in>>N>>C; 56 57 while(C>=5) C-=2; 58 59 p[63]=true; 60 go(63,C); 61 int x,y; 62 for(int i=0;i!=6;++i) mark[i]=-1; 63 for(in>>x;x!=-1;in>>x) 64 { 65 y=(x-1)%6; 66 if(mark[y]==-1) mark[y]=1; 67 else if(mark[y]==0) 68 { 69 out<<"IMPOSSIBLE"<<endl; 70 in.close(); out.close(); 71 return 0; 72 } 73 } 74 for(in>>x;x!=-1;in>>x) 75 { 76 y=(x-1)%6; 77 if(mark[y]==-1) mark[y]=0; 78 else if(mark[y]==1) 79 { 80 out<<"IMPOSSIBLE"<<endl; 81 in.close(); out.close(); 82 return 0; 83 } 84 } 85 //for(int i=0;i!=6;++i) cout<<"mark["<<i<<"]="<<mark[i]<<endl; 86 87 bool t=false; 88 for(int kk=0,k=0;k!=64;++k,kk=0) 89 { 90 for(int i=0;i!=6;++i) kk+=((bool)(k&(1<<i)))*(1<<(6-i-1)); 91 //cout<<"k= "; print(cout,k); 92 //cout<<"kk="; print(cout,kk); 93 //cout<<endl; 94 if(p[kk] && ok(kk)) { print(out,kk); t=true; } 95 } 96 if(!t) out<<"IMPOSSIBLE"<<endl; 97 98 in.close(); out.close(); 99 return 0; 100 }
posted on 2015-05-01 17:41 IceDream61 阅读(360) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端