USACO Section 2.2 Party Lamps

/*
ID: lucien23
PROG: lamps
LANG: C++
*/
/*
 * 此题的技巧之处就是需要注意到任何button只要按下2的倍数次就相当于没有按
 * 所以其实只需要考虑4个按钮,每个按钮是否被有效按下过一次就好
 * 直接使用枚举法,一共只有2^4=16种情况
 * 对于每种情况需要知道被按下的有效次数(也就是被按下过的按钮数),必须满足
 * (C-有效次数)%2=0才行,这样其他次数才能视为无效
 * 然后验证各种情况是否符合要求,将符合要求的情况按序输出即可
 */
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

bool compPro(int *strNum1, int *strNum2)
{
	int i = 0;
	while (1)
	{
		if (strNum1[i] < strNum2[i])
			return true;
		else if (strNum1[i] > strNum2[i])
			return false;
		i++;
	}
}

int main()
{
	ifstream infile("lamps.in");
	ofstream outfile("lamps.out");
	if(!infile || !outfile)
	{
		cout << "file operation failure!" << endl;
		return -1;
	}

	int N, C;
	vector<int> vecOnLamps, vecOffLamps;
	vector<int*> results;
	infile >> N >> C;
	int num;
	infile >> num;
	while (num != -1)
	{
		vecOnLamps.push_back(num);
		infile >> num;
	}
	infile >> num;
	while (num != -1)
	{
		vecOffLamps.push_back(num);
		infile >> num;
	}
	int count = 0;
	for (int i=0; i<16; i++)
	{
		int *lamps = new int[N];
		for (int j=0; j<N; j++)
		{
			lamps[j] = 1;
		}

		int tempCnt = 0;
		for (int j=0; j<4; j++)
		{
			int temp = 1 << j;
			if ((temp & i) == temp)
				tempCnt++;
		}
		if (C < tempCnt || (C - tempCnt) % 2 != 0)
		{
			delete[] lamps;
			continue;
		}

		if (((1 << 0) & i) == (1 << 0))
		{
			for (int j=0; j<N; j++)
			{
				if (lamps[j] == 0)
					lamps[j] = 1;
				else
					lamps[j] = 0;
			}
		}

		if (((1 << 1) & i) == (1 << 1))
		{
			for (int j=0; j<N; j++)
			{
				if ((j+1)%2 == 1)
				{
					if (lamps[j] == 0)
						lamps[j] = 1;
					else
						lamps[j] = 0;
				}
			}
		}

		if (((1 << 2) & i) == (1 << 2))
		{
			for (int j=0; j<N; j++)
			{
				if ((j+1)%2 == 0)
				{
					if (lamps[j] == 0)
						lamps[j] = 1;
					else
						lamps[j] = 0;
				}
			}
		}

		if (((1 << 3) & i) == (1 << 3))
		{
			for (int j=0; j<N; j++)
			{
				if ((j+1)%3 == 1)
				{
					if (lamps[j] == 0)
						lamps[j] = 1;
					else
						lamps[j] = 0;
				}
			}
		}

		bool flag = true;
		for (vector<int>::iterator it=vecOnLamps.begin(); it!=vecOnLamps.end(); it++)
		{
			if (lamps[*it-1] != 1)
			{
				flag = false;
				break;
			}
		}

		if (!flag)
		{
			delete[] lamps;
			continue;
		}

		for (vector<int>::iterator it=vecOffLamps.begin(); it!=vecOffLamps.end(); it++)
		{
			if (lamps[*it-1] != 0)
			{
				flag = false;
				break;
			}
		}

		if (flag)
		{
			count++;
			results.push_back(lamps);
		} else {
			delete[] lamps;
		}
	}

	if (count == 0)
	{
		outfile << "IMPOSSIBLE" << endl;
	} else {
		sort(results.begin(), results.end(), compPro);
		for (int i=0; i<count; i++)
		{
			for (int j=0; j<N; j++)
			{
				outfile << results[i][j];
			}
			outfile << endl;
		}
	}

	return 0;
}

USACO Section 2.2 Party Lamps

时间: 2024-08-27 02:15:13

USACO Section 2.2 Party Lamps的相关文章

USACO Section 2.1 Healthy Holsteins

/* ID: lucien23 PROG: holstein LANG: C++ */ #include <iostream> #include <fstream> #include <vector> using namespace std; bool compFun(int x, int y) { int temp, i = 0; while (true) { temp = 1 << i; if (temp&x > temp&y) {

USACO Section 2.2 Runaround Numbers

/* ID: lucien23 PROG: runround LANG: C++ */ #include <iostream> #include <fstream> #include <cstring> using namespace std; int main() { ifstream infile("runround.in"); ofstream outfile("runround.out"); if(!infile || !

USACO Section 2.2 Preface Numbering

/* ID: lucien23 PROG: preface LANG: C++ */ #include <iostream> #include <fstream> #include <string> #include <map> using namespace std; int main() { ifstream infile("preface.in"); ofstream outfile("preface.out")

【USACO 2.2】Party Lamps

四种开关,n盏灯,1:改变所有灯状态,2:改变奇数灯状态,3:改变偶数灯状态,4:改变3k+1灯状态 给你按开关的总次数c和部分灯限制条件(开或关),一开始都是开着的.($c \leq 10000,n \leq 100$) 我直接考虑每个开关按了奇数次或偶数次,因为顺序和总次数不影响结果,重要的是每种开关按的次数是奇数还是偶数次. 题解里有个flip[i]= (1<<6-1)&0x55 和与上0xAA,分别代表2.3开关,因为0x55就是01010101,0xAA就是10101010,

USACO Section 2.1 Sorting a Three-Valued Sequence

/* ID: lucien23 PROG: sort3 LANG: C++ */ #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; void exchange(int nums[], int begin, int end, int N, int x); int sum = 0; int main() { ifst

USACO Section 1.1 Your Ride Is Here

原题: Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often come to collect loyal supporters from here on Earth. Unfortunately, they only have room to pick up one group of followers on each trip. They do, how

[IOI1996] USACO Section 5.3 Network of Schools(强连通分量)

nocow上的题解很好. http://www.nocow.cn/index.php/USACO/schlnet 如何求强连通分量呢?对于此题,可以直接先用floyd,然后再判断. ---------------------------------------------------------------------------------- #include<cstdio> #include<iostream> #include<algorithm> #includ

USACO Section 5.3 Big Barn(dp)

USACO前面好像有类似的题目..dp(i,j)=min(dp(i+1,j),dp(i+1,j+1),dp(i,j+1))+1  (坐标(i,j)处无tree;有tree自然dp(i,j)=0) .dp(i,j)表示以坐标(i,j)为左上角的barn边长最大值,dp(i+1,j),dp(i,j+1)分别表示向右和向下能扩展的最大边长,但是以此为正方形时,右下方的一个格子没有考虑到,所以就+个dp(i+1,j+1).边界为:dp(i,j)=1(i==n-1或j==n-1). -----------

USACO Section 3.3 Camlot

BFS.先算出棋盘上每个点到各个点knight需要的步数:然后枚举所有点,其中再枚举king是自己到的还是knight带它去的(假如是knight带它的,枚举king周围的2格(网上都这么说,似乎是个结论?还是usaco数据太弱了?不过看跑出来的时间,全部枚举或许也可以)).一开始觉得挺麻烦的,不过只要思路清晰写起来应该也没多大问题.大概就是这样了. #include<cstdio> #include<iostream> #include<algorithm> #inc