这道题很简单
但我看了题解 大多是打表
大分类讨论
反正一大堆代码
没那么麻烦啊
一点:
我们只需要枚举操作(1-4)的奇偶
for(reg i = 0;i <= 1;i++)
{
for(reg j = 0;j <= 1;j++)
{
for(reg k = 0;k <= 1;k++)
{
int res = c - i - j - k;
if(res < 0) continue;
res %= 2;
count_(i,j,k,res);
}
}
}
可以保证正确性
即我们可以证明若有
(a+b+c+d=E)
已知 (a,b,c)的奇偶
那么可以确定(d)的奇偶
证明很简单 这里就略了
枚举一种状态后
再检查可行性
for(reg q = 0;q < light.size();q++)
if(check(i,j,k,l,light[q])) return;
for(reg q = 0;q < dark.size();q++)
if(!check(i,j,k,l,dark[q])) return;
(check)为当前位置按的次数
注意要排序输出
因为我懒 所以用优先队列了
如果去掉读优和一些不必要的东西后 应该是最短的了
/*
ID:death_r2
TASK:lamps
LANG:C++
*/
#include <queue>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define reg register int
#define isdigit(x) ('0' <= x&&x <= '9')
template<typename T>
inline T Read(T Type)
{
T x = 0,f = 1;
char a = getchar();
while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
return x * f;
}
vector<int> light,dark;
int n,c;
priority_queue<string,vector<string>,greater<string> > ans;
inline bool check(int i,int j,int k,int l,int num)
{
int g = num & 1;
if((i + (j & g) + (k & (!g)) + ((num % 3 == 1) & l)) & 1) return 1;
return 0;
}
inline void count_(int i,int j,int k,int l)
{
for(reg q = 0;q < light.size();q++)
if(check(i,j,k,l,light[q])) return;
for(reg q = 0;q < dark.size();q++)
if(!check(i,j,k,l,dark[q])) return;
string a;
for(reg v = 1;v <= n;v++)
{
if(check(i,j,k,l,v)) a = a + '0';
else a = a + '1';
}
ans.push(a);
}
int main()
{
freopen("lamps.in","r",stdin);
freopen("lamps.out","w",stdout);
n = Read(1),c = Read(1);int x = Read(1);
while(x != -1)
{
light.push_back(x);
x = Read(1);
}
x = Read(1);
while(x != -1)
{
dark.push_back(x);
x = Read(1);
}
for(reg i = 0;i <= 1;i++)
{
for(reg j = 0;j <= 1;j++)
{
for(reg k = 0;k <= 1;k++)
{
int res = c - i - j - k;
if(res < 0) continue;
res %= 2;
count_(i,j,k,res);
}
}
}
if(ans.empty())
{
printf("IMPOSSIBLE
");
} else {
while(!ans.empty())
{
cout << ans.top() << endl;
ans.pop();
}
}
return 0;
}