派对灯 Party Lamps

这道题很简单

但我看了题解 大多是打表

大分类讨论

反正一大堆代码

没那么麻烦啊

一点:

我们只需要枚举操作\(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\n");
	} else {
		while(!ans.empty())
		{
			cout << ans.top() << endl;
			ans.pop();
		}
	}
	return 0;
}
posted @ 2019-11-25 13:28  resftlmuttmotw  阅读(224)  评论(0编辑  收藏  举报