zoukankan      html  css  js  c++  java
  • D. XOR-gun 思维和 + 前缀

    D. XOR-gun 思维 + 前缀和

    题目大意:

    给你一个大小为 (n) 的不递减数组,你可以选择两个连续的两个数,然后把这两个数删掉,把他们的异或值放到这个位置来。问,最少经过多少次,使得这个数组变成一个不是不递减的序列。

    题解:

    • 首先,容易发现,如果有三个数的最高位是一样的,那么只需要一次就可以了
    • 然后,如果 n > 60,那么一定会存在有三个数的最高位是一样的
    • 所以就可以把 n 的范围,缩小到 60
    • 最后就有两个策略:
      • 第一种就是连续的一段异或即可,
      • 第二种就是两个连续段
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 10;
    int a[maxn],sum[maxn];
    
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i] = sum[i-1]^a[i];
        if(n>60) printf("1
    ");
        else {
            int ans = 1e9;
            for(int i=1;i<=n;i++){
                for(int j=i;j<=n;j++){
                    int now = sum[j]^sum[i-1];
                    if(now<a[i-1]||(j+1<=n&&now>a[j+1])) ans = min(ans,j-i);
    //                printf("i = %d j = %d now = %d %d ans = %d
    ",i,j,now,a[j+1],ans);
                }
            }
            for(int i=1;i<=n;i++){
                for(int j=i;j<=n;j++){
                    for(int k=j+1;k<=n;k++){
                        int x = sum[j]^sum[i-1],y = sum[k]^sum[j];
                        if(x>y) ans = min(ans, k - i - 1);
                    }
                }
            }
            if(ans>=1e9) printf("-1
    ");
            else printf("%d
    ",ans);
        }
    }
    
  • 相关阅读:
    微信公众平台开发者中心安全模式消息体加解密实现
    AES对称加密算法原理
    Token验证失败
    PaySignKey
    UVA 11732
    lua中的pairs和ipairs差别
    【shell学习笔记】curl命令总结
    视频监控系统:C/S &amp; B/S
    Android app开发中用户协议(使用条款)文字自己主动换行
    uva 10154
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14583912.html
Copyright © 2011-2022 走看看