• POJ1063 Flip and Shift 数学分析&运用守恒定理


    题意:给定一个数N (10 <=N <= 30),然后给你N个数,这N个数由0和1组成,这N个数可以看做是一个环.然后现在又一种操作,可以将连续的三个数进行翻转,也可以将整个序列顺时针旋转一圈.现在问是否存在通过一个操作来是的实现将所有的1都靠在一起.

    这题刚开始分析的时候只注意到连续的三个数的8种组合情况,然后只有四种情况是在翻转过程中产生变化的.但是这样的想法还是没有多大帮助.实在是不会了.因为我的整个思路在于去构造一个方法能够使得所有的1都连在一起.而题目只要我们输出YES或者是NO.参看了题解后恍然大悟:这里只要从奇偶性方面去思考就可以了.

    当我们从奇偶性去看一个状态的时候,最后的状态是什么呢,所有的1都连在一起,如果是奇数个1的话,那么1所有位置的奇偶性之差为1,偶数个1则为零.我们在观察其实所谓的翻转就是将某个点的坐标+或者是-2,这并不影响其奇偶性. 当N为奇数的时候,那么一直+2的话,那么最后的时候会出现N和1两个奇数连着的情况,因此奇偶性发生了突变.也就是我如果N是奇数的话,那么我们能够构造出1在奇数位置和偶数位置的差不超过1.如果N为偶数的话,那么无论如何翻转,奇偶性终将不变,因此如果初始状态不满足的话就输出NO了.

    综上所述:

    当N为奇数的时候,总是输出YES

    当N为偶数的时候,如果出现在奇数位上的1和偶数位上的1之差不超过1的话输出YES,否则输出NO

    代码如下:

    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #define MAXN 35
    using namespace std;
    
    int main() {
        int T, N;
        scanf("%d", &T);
        while (T--) {
            int odd = 0, even = 0;
            int c;
            scanf("%d", &N);
            for (int i = 0; i < N; ++i) {
                scanf("%d", &c);
                if (c) i&1 ? ++odd : ++even; 
            }
            if (N & 1) puts("YES");
            else puts(abs(odd-even)<=1 ? "YES" : "NO");
        }
        return 0;    
    }
  • 相关阅读:
    CSP201412-2:Z字形扫描
    CSP201409-2:画图
    CSP201403-2:窗口
    CSP201312-2:ISBN号码
    CSP201709-1:打酱油
    CSP201703-1:分蛋糕
    CSP201612-1:中间数
    LOAM笔记及A-LOAM源码阅读
    特征值、特征向量与PCA算法
    欧几里得与区域生长算法
  • 原文地址:https://www.cnblogs.com/Lyush/p/2848185.html
Copyright © 2020-2023  润新知