您的位置:首页 > 大数据 > 人工智能

USACOTrainning.Party Lamps

2010-04-30 11:23 204 查看
大意是用N个灯,有4种操作,然后有些限制条件,操作C次后,可能出现的灯的状态。

刚开始直接用N个灯来BFS,对状态数的数目不太了解,而且还不是一层一层的扩展,还跨过层,也就是说状态数就变成C*(<2^N)了,而且还没判重,弄晕掉。

后来,仔细观察状态,发现对于N个灯泡,4种操作时有循环节的,为6,就是说状态数只有2^6,然后用BFS一层一层扩展,扩展到C层,复杂度就是2^6 * C,BFS的过程其实可以看成从X层到X+1层的扩展,然后用个S[1 << 6][2]标记数组来标记X,X+1层的状态,进行判重。在这过程中都不对状态数进行状态限制,直到扩展到C层时,判断限制条件,符合就放进ANS。注意2进制的字典序和高地位顺序问题。

#include <iostream>
#include <string>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <time.h>
#include <queue>
#include <set>
using namespace std;

int N, C, SN;

int s[1 << 6][2];
int on, off;

vector<int>ans;

bool check(int t)
{
if(((t & on) != on))  return false;
if(t & off)  return false;
return true;
}

string turn(int x, int len)
{
string res = "";
for(int i = 0; i < len; i++)
{
if(x & (1 << i))  res.push_back('1');
else  res.push_back('0');
}
return res;
}

void go()
{
//SN = (N - 1) % 6 + 1;
if(N > 6)  SN = 6;
else  SN = N;
memset(s, 0, sizeof(s));
vector<pair<int, int> >v;
int mask[4];
memset(mask, 0, sizeof(mask));
mask[0] = (1 << SN) - 1;
for(int i = 0; i < SN; i += 2)  mask[1] |= (1 << i);
for(int i = 1; i < SN; i += 2)  mask[2] |= (1 << i);
for(int i = 0; i < SN; i += 3)  mask[3] |= (1 << i);
v.push_back(make_pair((1 << SN) - 1, 0));
s[(1 << SN) - 1][0] = 1;
for(int i = 0; i < v.size(); i++)
{
int a = v[i].first;
int b = v[i].second;
if(b > C)  break;
if(b == C)// && check(a))
{
if(check(a) == false)  continue;
ans.push_back(a);
}
s[a][b % 2] = 0;//已经不在队列
//扩展
int t;
for(int j = 0; j < 4; j++)
{
t = a ^ mask[j];
if(s[t][(b + 1) % 2] == 0)
{
s[t][(b + 1) % 2] = 1;
v.push_back(make_pair(t, b + 1));
}
}
}
if(ans.size() == 0)
{
printf("IMPOSSIBLE\n");
return;
}
vector<string>str;
for(int i = 0; i < ans.size(); i++)
{
str.push_back(turn(ans[i], SN));
}
sort(str.begin(), str.end());
for(int i = 0; i < str.size(); i++)
{
for(int j = 0; j < N; j++)  printf("%c", str[i][j % 6]);
printf("\n");
}
}

int main()
{
freopen("lamps.in", "r", stdin);
freopen("lamps.out", "w", stdout);

scanf("%d%d", &N, &C);
int t;
on = 0;
off = 0;
while(scanf("%d", &t) && t != -1)
{
t--;
t %= 6;
on |= (1 << t);
}
while(scanf("%d", &t) && t != -1)
{
t--;
t %= 6;
off |= (1 << t);
}
go();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: