USACO 2.2.4 Party Lamps

注意有状态重复,所以实际需要统计的状态并不多

以及有效按钮数<=4

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
//#define LOCAL

using namespace std;

#ifdef LOCAL
ofstream fout ("out.txt");
ifstream fin ("in.txt");
#else
ofstream fout ("lamps.out");
ifstream fin ("lamps.in");
#endif

int res[1<<10]; // save the state
int num_on = 0;
int num_off = 0;
int on[10];
int off[10];
int used[1000];
int num_light;
int num_change;
int num_res = 0;


int change1(int s)
{
	s = s^((1<<6)-1);
	return s;
}

int change2(int s)
{
	s = s^(052);
	return s;
}

int change3(int s)
{
	s = s^(025);
	return s;
}

int change4(int s)
{
	s = s^(044);
	return s;
}

int max_s = -1;

bool check(int state)
{
    //max_s = max(max_s, state);
    if(used[state]==1)
        return 0;
	for (int i = 0; i < num_on; ++i)
	{
		if((state&(1<<(6 - on[i])))==0)
			return 0;
	}
	for (int i = 0; i < num_off; ++i)
	{
		if((state&(1<<(6 - off[i])))!=0)
			return 0;
	}
	return 1;
}

void dfs(int now, int state)
{
	if(now==num_change)
	{
		if(check(state))
        {
			res[num_res++] = state;
			used[state] = 1;
        }
		return;
	}
	dfs(now+1, change1(state));
	dfs(now+1, change2(state));
	dfs(now+1, change3(state));
	dfs(now+1, change4(state));
}

bool cmp(const int &a, const int &b)
{
    return a < b;
}

int main() {

	fin >> num_light >> num_change;

	while(num_change>4)
        num_change -= 2;

	int temp;
	while(1)
	{
		fin >> temp;
		if(temp==-1)
			break;

		if(temp%6==0)
			temp = 6;
		else
			temp = temp%6;

		on[num_on++] = temp;
	}

	temp = 1;
	while(1)
	{
		fin >> temp;
		if(temp==-1)
			break;
		if(temp%6==0)
			temp = 6;
		else
			temp = temp%6;

		off[num_off++] = temp;
	}

	int now = (1<<6) - 1;
	dfs(0, now);
    //cout<<now<<endl;
    //cout<<max_s<<endl;//

	if(num_res==0)
	{
		fout<<"IMPOSSIBLE\n";
		return 0;
	}

	sort(res, res+num_res, cmp);

	// for (int i = 0; i < num_res; ++i)
	// {
	// 	fout<<res[i]<<endl;
	// }

	for (int i = 0; i < num_res; ++i)
	{
		int temp = res[i];
		int t = 0;
		for (int j = 0; ; ++j)
		{
			if(t==num_light)
				break;
			if(t%6==0)
				j = 0;
			if((temp&(1<<(5-j)))!=0)
				fout<<1;
			else
				fout<<0;
			t++;
		}
		fout<<endl;
	}
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值