ACM学习-POJ-1063-Flip and Shift

 

ACM学习-POJ-1063-Flip and Shift

分类: c/c++ 一步一步学算法 剑指POJ   199人阅读  评论(0)  收藏  举报

菜鸟学习ACM,纪录自己成长过程中的点滴。

学习的路上,与君共勉。

 ACM学习-POJ-1063-Flip and Shift 

Flip and Shift
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 6623 Accepted: 3086

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。因此想要黑色珠子全都连在一起,则要求奇数位上的黑色珠子数量和偶数位上的黑色珠子数量之差的绝对值要小于等于1。

对于第二种情况,珠子总数为奇数,这种情况一定可以达到目标,因为如果任意相邻两珠子可交换则一定可以达到目标。对于总数为奇数的情况,相当于将一种相邻两珠子可交换的排列方式更改了珠子的排列顺序,但交换方式不变。例如,7个珠子,1357246。把这个序列首尾相接则形成了一个相邻两两可交换的环,可以达到任何目标状态。

下面给出AC代码:
[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <math.h>  
  3. #define MAX_NUM 31  
  4.   
  5. int main()  
  6. {  
  7.     int n;  
  8.     int i;  
  9.     int arr_[MAX_NUM];  
  10.     int num_;  
  11.     int count_odd;  
  12.     int count_even;  
  13.       
  14.     scanf("%d",&n);  
  15.       
  16.     while (n--)  
  17.     {  
  18.         scanf("%d", &num_);  
  19.         for (i=0; i<num_; i++)  
  20.         {  
  21.             scanf("%d", &arr_[i]);  
  22.         }  
  23.         if (num_ % 2 == 1)  
  24.         {  
  25.             printf("YES\n");  
  26.         }  
  27.         else  
  28.         {  
  29.             count_even = 0;  
  30.             count_odd = 0;  
  31.             for (i=0; i<num_; i++)  
  32.             {  
  33.                 if (arr_[i] == 1)  
  34.                 {  
  35.                     if (i % 2)  
  36.                     {  
  37.                         count_odd++;  
  38.                     }  
  39.                     else  
  40.                         count_even++;  
  41.                 }  
  42.                   
  43.             }  
  44.             if ( abs(count_even - count_odd) <= 1 )  
  45.             {  
  46.                 printf("YES\n");  
  47.             }  
  48.             else  
  49.             {  
  50.                 printf("NO\n");  
  51.             }  
  52.         }          
  53.     }  
  54.       
  55.     return 0;  
  56. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值