USACO-Section2.2 Party Lamps [枚举]
来源:互联网 发布:windows arm模拟器 编辑:程序博客网 时间:2024/06/11 15:39
题目大意
在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码。 这些灯都连接到四个按钮:
按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄灭,本来是关着的灯被点亮。
按钮2:当按下此按钮,将改变所有奇数号的灯。
按钮3:当按下此按钮,将改变所有偶数号的灯。
按钮4:当按下此按钮,将改变所有序号是3*K+1(K>=0)的灯。例如:1,4,7…
一个计数器C记录按钮被按下的次数。当宴会开始,所有的灯都亮着,此时计数器C为0。
你将得到计数器C(0<=C<=10000)上的数值和经过若干操作后某些灯的状态。写一个程序去找出所有灯最后可能的与所给出信息相符的状态,并且没有重复。
题解
4个按钮,按下偶数次和没有按下的效果是一样的。所以总共有16种不同的组合。
我们可以对这16种组合都枚举一下,然后判断是否满足条件。最后按顺序输出满足条件的结果。
有2种方法枚举,一种是递归搜索4层,另外一种是直接for循环16次,根据位运算来辨别4个开关的状态。这里可以再次巩固下bitset的用法。下面给出两种代码:
代码1
#include <iostream>#include <fstream>#include <vector>#include <queue>#include <bitset>#include <cstring>#include <algorithm>#define MAXN 110#define cin fin#define cout foutusing namespace std;ifstream fin("lamps.in");ofstream fout("lamps.out");typedef bitset<MAXN> bit;priority_queue<string, vector<string>, greater<string> > ans;bit ON, OFF;bit mash, zero, tmp;bit button[4];int N, C, M;bool pressed[4];int flag;void init() { cin >> N >> C; zero.reset(); for (int i = 0; i < N; i++) { mash.set(i); button[0].set(i); if (i%2) button[2].set(i); else button[1].set(i); if (!(i%3)) button[3].set(i); } int t; while (cin >> t) { if (t == -1) break; ON.set(t-1); } while (cin >> t) { if (t == -1) break; OFF.set(t-1); } M = min(C, 4);// 只有4种操作 flag = C % 2;}bool is_ok(bit stat) { if (((stat | ON) & mash) != stat) return false; if (((stat & OFF) & mash) != zero) return false; return true;}void dfs(int step, int cnt) { if (step == 4) { if (cnt % 2 == flag && cnt <= M) { tmp = mash; for (int i = 0; i < 4; i++) { if (pressed[i]) { tmp = (tmp ^ button[i]) & mash; } } if (is_ok(tmp)) { string str = tmp.to_string().substr(MAXN-N); reverse(str.begin(), str.end()); ans.push(str); } } } else { pressed[step] = true; dfs(step+1, cnt+1); pressed[step] = false; dfs(step+1, cnt); }}int main() { init(); dfs(0, 0); if (ans.empty()) cout << "IMPOSSIBLE" << endl; while (!ans.empty()) { cout << ans.top() << endl; ans.pop(); } return 0;}
代码2
用位运算来枚举所有的16种情况。
//#include<iostream>#include<fstream>#include<bitset>#include<sstream>#include<algorithm>using namespace std;ifstream cin("lamps.in");ofstream cout("lamps.out");int n, c, ans=0, a[101]={0}, b[101]={0};string str[17];bitset<101> bit(0);void change(int f, bitset<101> &bit);bool is_ok(string &s);int main(){ int r=0; cin >> n >> c; while(cin>>a[r]) if(a[r++]==-1)break; r=0; while(cin>>b[r]) if(b[r++]==-1)break; for(int i=0; i<=15; i++) { bit.set(); bitset<4> t(i); if((t.count()%2==c%2) && (t.count()<=c)) //有效操作数和实际操作数是同奇偶的,且有效操作数小于实际操作数 { stringstream s; string ts; for(int j=0; j<4; j++) if(t[j]) change(j,bit); for(int j=0; j<n; j++) s << bit[j]; s >> ts; if(is_ok(ts)) str[ans++] = ts;//判断是否满足给定的条件 } } sort(str,str+ans); for(int i=0; i<ans; i++) cout << str[i] << endl; if(!ans) cout << "IMPOSSIBLE" << endl; return 0;}void change(int f, bitset<101> &bit){ switch(f) { case 0: for(int i=0; i<n; i++)bit.flip(i); break; case 1: for(int i=0; i<n; i+=2) bit.flip(i); break; case 2: for(int i=1; i<n; i+=2) bit.flip(i); break; case 3: for(int i=0; i<n; i+=3) bit.flip(i); break; }}bool is_ok(string &s){ int r=0; while(a[r]!=-1) if(s[a[r++]-1] == '0') return false; r=0; while(b[r]!=-1) if(s[b[r++]-1] == '0') return false; return true;}
阅读全文
0 0
- USACO-Section2.2 Party Lamps [枚举]
- USACO-Section2.2 Party Lamps
- USACO section2.2 Party Lamps题解&思路
- USACO-Section2.2 Party Lamps【深度优先搜索】
- USACO-Section 2.2 Party Lamps (枚举)
- USACO 2.2 Party Lamps (lamps)
- 【其他】【USACO】Party Lamps
- USACO 2.2 Party Lamps
- USACO Party Lamps
- usaco Party Lamps
- [USACO]Party Lamps
- USACO:Party Lamps
- USACO-Party Lamps
- USACO 2.2 Party Lamps
- usaco Party Lamps report
- USACO-Party Lamps
- usaco party lamps
- USACO 2.2Party Lamps
- Zookeeper集群搭建(伪集群)
- Windows驱动开发环境搭建(Visual Studio 2015 + WDK)
- 读写XML
- java微信开发框架wechat4j入门教程
- 虚拟机安装SSH服务
- USACO-Section2.2 Party Lamps [枚举]
- Jetson TX2板载相机opencv调用打开
- java中collections中sort方法
- css_day03_继承性
- angularjs学习总结 详细教程
- HTML/CSS基础学习总结
- Java对象序列化
- 贝塞尔曲线与CSS3动画、SVG和canvas的基情
- 【贪心枚举】拨钟问题