POJ3185 The Water Bowls 反轉(開關)

Description

The cows have a line of 20 water bowls from which they drink. The bowls can be either right-side-up (properly oriented to serve refreshing cool water) or upside-down (a position which holds no water). They want all 20 water bowls to be right-side-up and thus use their wide snouts to flip bowls. 

Their snouts, though, are so wide that they flip not only one bowl but also the bowls on either side of that bowl (a total of three or -- in the case of either end bowl -- two bowls). 

Given the initial state of the bowls (1=undrinkable, 0=drinkable -- it even looks like a bowl), what is the minimum number of bowl flips necessary to turn all the bowls right-side-up?

Input

Line 1: A single line with 20 space-separated integers

Output

Line 1: The minimum number of bowl flips necessary to flip all the bowls right-side-up (i.e., to 0). For the inputs given, it will always be possible to find some combination of flips that will manipulate the bowls to 20 0's.

Sample Input

0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0

Sample Output

3

Hint

Explanation of the sample: 

Flip bowls 4, 9, and 11 to make them all drinkable: 
0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 [initial state] 
0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 [after flipping bowl 4] 
0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 [after flipping bowl 9] 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [after flipping bowl 11]

        這題屬於反轉(開關)類型的題,典型的特徵就是:
1,反轉的先後順序是不重要的;
2,主動對一個開關進行2次或2次以上的反轉是多餘的。
        這題,如果條件是每次必須反轉3個碗的話,那麼就很簡單,先考慮最左端的碗,如果碗朝下,那麼這個碗必須反轉,同時帶動後面兩個碗一起反轉,這樣的話問題的規模就減少了一個,然後重複此方法判斷。
        但是條件是在兩端可以出現同時只反轉兩個碗的情況,這時候只要先枚舉一下兩端反轉兩個碗的所有情況,然後就可以把它當成每次必須反轉3個碗進行處理就可以了。
#include <stdio.h>
#include <vector>
#include <math.h>
#include <string.h>
#include <string>
#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stack>
#include <map>

using namespace std;

int main()
{
#ifdef _DEBUG
	freopen("e:\\in.txt", "r", stdin);
#endif
	int side[21];
	int side1[21];
	for (int i = 0; i < 20; i ++)
	{
		scanf("%d", &side[i]);
	}
	int minCount = 50;
	for (int i = 0; i < 4;i++)
	{
		int count1 = 0;
		memcpy(side1, side, sizeof(side));
		if (i == 1)
		{
			side1[0]++;
			side1[1]++;
			count1++;
		}
		else if (i == 2)
		{
			side1[18]++;
			side1[19]++;
			count1++;
		}
		else if (i == 3)
		{
			side1[0]++;
			side1[1]++;
			side1[18]++;
			side1[19]++;
			count1++;
			count1++;
		}
		for (int i = 0; i <= 17; i++)
		{
			if (side1[i] & 1)
			{
				side1[i] ++;
				side1[i + 1]++;
				side1[i + 2]++;
				count1++;
			}
		}
		if (!(side1[1] & 1 || side1[18] & 1 || side1[19] & 1))
		{
			if (minCount > count1)
			{
				minCount = count1;
			}
		}
	}
	printf("%d\n", minCount);
	return 1;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章