飛行員兄弟--算法競賽進階指南

題目描述:
“飛行員兄弟”這個遊戲,需要玩家順利的打開一個擁有16個把手的冰箱。
已知每個把手可以處於以下兩種狀態之一:打開或關閉。
只有當所有把手都打開時,冰箱纔會打開。
把手可以表示爲一個4х4的矩陣,您可以改變任何一個位置[i,j]上把手的狀態。
但是,這也會使得第i行和第j列上的所有把手的狀態也隨着改變。
請你求出打開冰箱所需的切換把手的次數最小值是多少。
輸入格式:
入一共包含四行,每行包含四個把手的初始狀態。
符號“+”表示把手處於閉合狀態,而符號“-”表示把手處於打開狀態。
至少一個手柄的初始狀態是關閉的。
輸出格式:
第一行輸出一個整數N,表示所需的最小切換把手次數。
接下來N行描述切換順序,每行輸入兩個整數,代表被切換狀態的把手的行號和列號,數字之間用空格隔開。
**注意:**如果存在多種打開冰箱的方式,則按照優先級整體從上到下,同行從左到右打開。

數據範圍:
1≤i,j≤4
輸入樣例:

-+--
----
----
-+--

輸出樣例:
6
1 1
1 3
1 4
4 1
4 3
4 4

AC代碼:

/*
解題思路: 
因爲是4X4的,也就是2的16次方個可能,是65536,數字不算大,可以直接暴力破解
枚舉這16個開關的每一個變化的可能性,如果符合,則記錄,最後比較出最小的一個輸出即可 
*/ 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <limits.h>
using namespace std;

int map[4][4];//1-打開,0+關閉 
int tmpMap[4][4];//複製數組
int minCount = INT_MAX;//先讓其爲最大 
vector<int> rx,ry;//最終結果的變化x,y座標 
void turn(int i, int j)
{
	//變化行 
	tmpMap[i][0] ^= 1;
	tmpMap[i][1] ^= 1;
	tmpMap[i][2] ^= 1;
	tmpMap[i][3] ^= 1;
	//變化列
	tmpMap[0][j] ^= 1; 
	tmpMap[1][j] ^= 1; 
	tmpMap[2][j] ^= 1; 
	tmpMap[3][j] ^= 1; 
	//i,j變化多了一次,再次變化一次
	tmpMap[i][j] ^= 1; 
} 

int main()
{
	//input 
	for(int i = 0; i < 4; i++)
	{
		for(int j = 0; j < 4; j++)
		{
			char tmp;
			scanf("%c",&tmp);
			if(tmp == '-') map[i][j] = 1;
			else map[i][j] = 0;
		}
		getchar();
	}
	
	//枚舉每一個開關是否變化 
	//用2進製表示即可,可以爲65526,再利用i>>j&1取出每一個二進制數是0或者1 
	for(int i = 0; i < 65536; i++)
	{
		memcpy(tmpMap, map, sizeof(int)*16);
		vector<int> tx, ty;
		int count = 0;
		for(int j = 0; j < 16; j++)
		{
			if(i >> j & 1)//取出那個位置上的數字 
			{
				count++;
				tx.push_back(j/4);
				ty.push_back(j%4);
				turn(j/4,j%4);
			}
		}
		
		//判斷是否符合要求
		bool flag = false;
		for(int r = 0; r < 4; r++)
		{
			for(int h = 0; h < 4; h++)
			{
				if(tmpMap[r][h] == 0) flag = true;
			}
		}
		//符合要求,交換 
		if(!flag)
		{
			if(count < minCount)
			{
				minCount = count;
				swap(tx,rx);
				swap(ty,ry);
			}
		}
	}
	
	//輸出結果 
	cout << minCount << endl;
	for(int i = 0; i < rx.size(); i++)
	{
		cout << rx[i]+1 << " "<< ry[i]+1 <<endl; 
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章