POJ 1222 EXTENDED LIGHTS OUT

在這裏插入圖片描述
參考題解[https://mp.csdn.net/mdeditor/87896325#]

#include <iostream>
#include <cstring>
using namespace std;

//取c的第i位
int GetBit(char c, int i)
{
	return (c >> i) & 1;  //先右移再與1相與
}

//設置c的第i位爲v
void SetBit(char &c, int i, int v)
{
	if(v)
		c |= (1 << i);  //將第i位設置爲1
	else
		c &= ~(1 << i); // 第i位設置爲0,其餘爲1,再進行與運算
}

//將c的第i位取反
void Flip(char &c, int i)
{
	c ^= (1 << i);	//第i位與1異或進行取反
}

void OutputResult(int t, char result[]) //輸出結果
{
	cout << "PUZZLE #" << t << endl;
	for(int i=0; i<5; i++) //5行
	{
		for(int j=0; j<6; j++)
		{
			cout << GetBit(result[i], j);	//得到第i行第j列元素
			if(j < 5)
				cout << " "; // 輸出5個空格最後一個不輸出空格
		}
		cout << endl;
	}
}

int main()
{
	char oriLights[5];		//最初燈矩陣,一個比特表示一盞燈,一個數組元素表示一行6個
	char lights[5];			//不停變化的燈矩陣
	char result[5];			//結果開關矩陣
	char switchs;			//某一行的開關狀態
	int T;
	cin >> T;
	for(int t=1; t<=T; t++)
	{
		memset(oriLights, 0, sizeof(oriLights));	//清零
		for(int i=0; i<5; i++)	//讀入燈的初始狀態
		{
			for(int j=0; j<6; j++)
			{
				int s;
				cin >> s;
				SetBit(oriLights[i], j, s);
			}
		}

		for(int n=0; n<64; n++)	//遍歷首行開關的64種狀態
		{
			memcpy(lights, oriLights, sizeof(oriLights));	//複製,每一次循環在原始數組上操作
			switchs = n;	//第i行的開關狀態
			for(int i=0; i<5; i++)
			{
				result[i] = switchs;	//第i行的開關方案
				for(int j=0; j<6; j++)
				{
					if(GetBit(switchs, j))
					{
						if(j > 0)
							Flip(lights[i], j-1);	//改左燈
						Flip(lights[i], j);		//改開關位置的燈
						if(j < 5)
							Flip(lights[i], j+1);	//改右燈
					}
				}
				if(i < 4)
					lights[i+1] ^= switchs;	//改下一行的燈
				switchs = lights[i];	//第i+1行開關方案和第i行燈的情況相同
			}
			if(lights[4] == 0)
			{
				OutputResult(t, result);
				break;
			}
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章