zoukankan      html  css  js  c++  java
  • hiho1509 异或排序

    题目链接

    题目大意:

    给定一个长度为 n 的非负整数序列 a[1..n]

    你需要求有多少个非负整数 S 满足以下两个条件:

    (1).0 ≤ S < 260

    (2).对于所有 1 ≤ i < n ,有 (a[i] xor S) ≤ (a[i+1] xor S)

    1 ≤ n ≤ 50

    0 ≤ a[i] < 260

    -------------------------------------------------------------------------------------

    开始看到题感觉无从下手,分析了一下才发现是到水题。

    维护一个60位的标记数组,用来表示S的第i位可以放置的数(11为置01都可,01为只可置0,10为只可置1,00为都不能放)。初始状态为11。

    开始时n个数在一个组内,要满足条件(2),n个数的最高位必须满足

                 1)全部为0或1;这时候该位可以放0或者1。

                 2)前几个数最高位为0,后面的数为1.(或者反过来),但不会出现01交替出现的情况;这时候该位只能放0或者1.

    对于情况1)仍把改组扔到次高位处理。

    对于情况2)可以把该组分成两组扔到次高位处理。

    #include <set>
    #include <map>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    
    #define MAX(a,b) ((a)>=(b)?(a):(b))
    #define MIN(a,b) ((a)<=(b)?(a):(b))
    #define OO 0x0fffffff
    using namespace std;
    typedef long long LL;
    const int N = 66;
    int digits[N][N];
    void getDigits(int id,LL data){
        for(int i=0;i<60;i++){
            digits[id][i]=(data&1L);
            data>>=1;
        }
    }
    int choice[N];
    int n;
    LL data;
    struct Node{
       int level;
       int spos,epos;
       int sdigit,scnt;
       Node(int tlevel,int tspos,int tepos){
           level = tlevel;
           spos = tspos;
           epos = tepos;
       }
       Node(){}
       int length(){
           return epos-spos+1;
       }
    };
    int main(){
        cin>>n;
        for(int i=0;i<n;i++) {
           cin>>data;
           getDigits(i,data);
        }
        for(int i=0;i<60;i++) choice[i] = 3;
    
        Node head(59,0,n-1);
        queue<Node> q;
        q.push(head);
        while(!q.empty()){
            Node cur = q.front(); q.pop();
            cur.sdigit = digits[cur.spos][cur.level];
            cur.scnt = 1;
            for(int r=cur.spos+1;r<=cur.epos;r++){
                if(digits[r][cur.level]==digits[r-1][cur.level])
                    cur.scnt++;
                else break;
            }
            if(cur.scnt==cur.length()){
                choice[cur.level]&=3;
                if(cur.level)
                    q.push(Node(cur.level-1,cur.spos,cur.epos));
            }
            else {
                choice[cur.level]&=(cur.sdigit+1);
                if(cur.level){
                    q.push(Node(cur.level-1,cur.spos,cur.spos+cur.scnt-1));
                    q.push(Node(cur.level-1,cur.spos+cur.scnt,cur.epos));
                }
            }
        }
        LL ans = 1;
        for(int i=0;i<60;i++){
            if(!choice[i]) {
                ans=0;
                break;
            }
            if(choice[i]==3) ans*=2;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Linux中权限管理之文件特殊权限
    Linux中权限管理之ACL权限
    Linux用户管理命令
    【并发编程】实现多线程的几种方式
    “数据中台”的再思考
    软件工程六大设计原则总结,案例演示
    你必须要知道的移动端开发知识
    【搞定面试官】你还在用Executors来创建线程池?会有什么问题呢?
    EasyCode实现数据库到Swagger全自动化
    【Java实例】使用Thumbnailator生成缩略图(缩放、旋转、裁剪、水印)
  • 原文地址:https://www.cnblogs.com/redips-l/p/6894197.html
Copyright © 2011-2022 走看看