1. 程式人生 > >POJ 1063——Flip and Shift

POJ 1063——Flip and Shift

Flip and Shift
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 7861Accepted: 3635

Description

This puzzle consists of a random sequence of m black disks and n white disks on an oval-shaped track, with a turnstile capable of flipping (i.e., reversing) three consecutive disks. In Figure 1, there are 8 black disks and 10 white disks on the track. You may spin the turnstile to flip the three disks in it or shift one position clockwise for each of the disks on the track (Figure 1). 

The goal of this puzzle is to gather the disks of the same color in adjacent positions using flips and shifts. (Figure 2) 

You are to write a program which decides whether a given sequence can reach a goal or not. If a goal is reachable, then write a message "YES"; otherwise, write a message "NO".

Input

The input consists of T test cases. The number of test cases ) (T is given in the first line of the input file. Each of the next T lines gives a test case. A test case consists of an integer, representing the sum of m and n, and a sequence of m+n 0s and 1s, representing an initial sequence. A 0 denotes a white disk and a 1 denotes a black disk. The sum of m and n is at least 10 and does not exceed 30. There is a space between numbers.

Output

The output should print either "YES" or "NO" for each test case, one per line.

Sample Input

2 
18 0 0 1 0 1 1 1 1 0 1 0 0 1 0 0 0 0 1 
14 1 1 0 0 1 1 1 0 0 1 1 0 1 0 

Sample Output

YES
NO

Source

題目大意:在一個橢圓形通道上,放置有一定數量的圓形小球,黑球用1表示,白球用0表示,若定義一個小球的位置是一個單位,每次可以將一個小球與相距兩個單位的小球交換,即位置i上的小球可以跟位置i-2或i+2位置的小球互換,問是否能通過交換使得所有黑球是連續的,所有白球是連續的。

解題思路:這題是我通過思考規律想出來的,假設一共有n個小球,若n是偶數,那麼不論怎樣變換在偶數位置上的小球始終在偶數位置上,奇數位置上的小球始終在奇數位置上,通過研究連續的小球發現,連續的小球中,處於偶數位置上的小球數目和處於奇數位置上的小球數目只差不會超過1;若n是奇數,,則小球總是可以通過交換到達橢圓通道上的任何一個位置,至於交換時會打亂位置的顧慮不必擔心。

至此,所有條件都出來了,輸出YES的條件:

(1)小球數目是奇數。

(2)選擇白球或者黑球,白球/黑球中偶數位置和奇數位置的數目之差不大於2

(3)全是黑球或全是白球

AC程式碼:

#include<stdio.h>


int main()
{
	int odd;
	int even;
	int black;
	int t;
	int i;
	int n;
	int s;
	int a[100];
	scanf("%d",&t);
	while(t--){
		odd=0;
		even=0;
		black=0;
		scanf("%d",&n);
		for(i=0;i<n;i++){
			scanf("%d",&a[i]);
			if(a[i]==1){
				black++;
				if(i%2==0){
				    even++;
			    }
			    else{
			    	odd++;
			    }
			}
		}
		if(even>odd){
			s=even;
			even=odd;
			odd=s;
		}
		if(black==0||black==n||n%2!=0){
			printf("YES\n");
		}
		else if(n%2==0&&(odd-even<=1)){
			printf("YES\n");
		}
		else{
			printf("NO\n");
		}
	}
	return 0;
}