参考:http://hi.baidu.com/enlighten09/blog/item/d9e9dac9147d260a01e9289d.html
是个可以很简单,仔细分析也可以很复杂的题目
首先,最后的灯亮的情况只有8种。每个操作只有做了和没做两种状态,所以4个操作就只有16种。把这16操作都实现一遍,就会发现只有8种最终状态了。分别是:
最终状态 按几次可以得到
0,0,0,0,0,0, 1,2,3
0,0,1,1,1,0, 2,3
0,1,0,1,0,1, 1,2,3
0,1,1,0,1,1, 1,4
1,0,0,1,0,0, 2,3
1,0,1,0,1,0, 1,2
1,1,0,0,0,1, 2,3
1,1,1,1,1,1 0,2,3
而c>=5时,c是奇数等效于c=1或3,c是偶数等效于c=2或4,所以可以看出c>=5时,所有的状态都能被按出来
所以我把c分为0,<5,>=5三种情况讨论。
还有一点就是不管多少个灯,在一种状态中,都是以前六个灯得状态循环的,所以只用考虑6个灯。
我的代码——有一个大问题
当n > 4时,对表进行0-7行遍历即可
可是当n < 4时,0-7行是选择性的进行比较,我不知道应该怎么自动判断,所以自己写了n = 0, n = 1,n = 2的各种情况,太弱的写法了……
上面范例里的方法是用一个数组把n = 1, 2, 3, 4时对应的情况给列出,int first_four[4][8]={{0,2,3,4,-1},{0,1,2,4,5,6,7,-1},{0,1,2,4,6,7,-1},{3,-1}}; 本质上也一样……
/*
ID: wangxin12
PROG: lamps
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <string.h>
#include <stack>
using namespace std;
int N;
int count;
vector<int> ON;
vector<int> OFF;
vector<int> ans;
int lamp[8][6] = {
{0,0,0,0,0,0},
{0,0,1,1,1,0},
{0,1,0,1,0,1},
{0,1,1,0,1,1},
{1,0,0,1,0,0},
{1,0,1,0,1,0},
{1,1,0,0,0,1},
{1,1,1,1,1,1},
}; //所有的8种final情况
bool check(int row);
int main() {
//input
ifstream fin("lamps.in");
ofstream fout("lamps.out");
fin>>N;
fin>>count;
int temp = 0;
while(true) {
fin>>temp;
if(temp != -1)
ON.push_back(temp);
else break;
}
while(true) {
fin>>temp;
if(temp != -1)
OFF.push_back(temp);
else break;
}
fin.close();
//BODY
int i, j;
if(count > 2) {
for(i = 0; i <= 7; i++) {
if(check(i)) ans.push_back(i);
}
if(ans.empty()) fout<<"IMPOSSIBLE"<<endl;
else {
for(i = 0; i < ans.size(); i++) {
for(j = 0; j < N; j++) {
fout<<lamp[ans[i]][ (j % 6) ];
}
fout<<endl;
}
}
}
if(count == 0) {
if(check(7)) ans.push_back(7);
if(ans.empty()) fout<<"IMPOSSIBLE"<<endl;
else {
for(i = 0; i < ans.size(); i++) {
for(j = 0; j < N; j++) {
fout<<lamp[ans[i]][ (j % 6) ];
}
fout<<endl;
}
}
}
if(count == 1) {
if(check(0)) ans.push_back(0);
if(check(2)) ans.push_back(2);
if(check(3)) ans.push_back(3);
if(check(5)) ans.push_back(5);
if(ans.empty()) fout<<"IMPOSSIBLE"<<endl;
else {
for(i = 0; i < ans.size(); i++) {
for(j = 0; j < N; j++) {
fout<<lamp[ans[i]][ (j % 6) ];
}
fout<<endl;
}
}
}
if(count == 2) {
for(i = 0; i <= 7; i++) {
if(i = 3) continue;
if(check(i)) ans.push_back(i);
}
if(ans.empty()) fout<<"IMPOSSIBLE"<<endl;
else {
for(i = 0; i < ans.size(); i++) {
for(j = 0; j < N; j++) {
fout<<lamp[ans[i]][ (j % 6) ];
}
fout<<endl;
}
}
}
fout.close();
return 0;
}
bool check(int row) {
//check on
for(int i = 0; i < ON.size(); i++) {
if( !lamp[row][ (ON[i] % 6) - 1]) return false;
}
//check off
for(int i = 0; i < OFF.size(); i++) {
if( lamp[row][ (OFF[i] % 6) - 1]) return false;
}
return true;
}
另外几个可以有启发的范例:http://blog.csdn.net/liveas/article/details/5664822
牛逼的用位运算的:
http://www.byvoid.com/blog/usaco-224-party-lamps/zh-hans/
http://hi.baidu.com/leokan/blog/item/c12ddc432cf88e1772f05d0b.html
这个人的代码思路清晰 http://blog.csdn.net/sjtuyunlei/article/details/6648138