#Codeforces Round #687 Div. 2 _D. XOR-gun

本文探讨了一道编程竞赛题目,涉及到数组操作和位运算。题目要求通过XOR操作破坏一个非递减数组的性质,求最少操作次数。通过分析,发现当存在连续三个数字最高位相同时,最少操作次数为1。文章提供了详细的代码实现,并解释了代码逻辑,包括关键的位运算和动态规划优化。此外,还分享了未能找到解决方案时返回-1的判断条件。
摘要由CSDN通过智能技术生成

题目链接在此!

D. XOR-gun

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Arkady owns a non-decreasing array 𝑎1,𝑎2,…,𝑎𝑛. You are jealous of its beauty and want to destroy this property. You have a so-called XOR-gun that you can use one or more times.

In one step you can select two consecutive elements of the array, let’s say 𝑥 and 𝑦, remove them from the array and insert the integer 𝑥⊕𝑦 on their place, where ⊕ denotes the bitwise XOR operation. Note that the length of the array decreases by one after the operation. You can’t perform this operation when the length of the array reaches one.

For example, if the array is [2,5,6,8], you can select 5 and 6 and replace them with 5⊕6=3. The array becomes [2,3,8].

You want the array no longer be non-decreasing. What is the minimum number of steps needed? If the array stays non-decreasing no matter what you do, print −1.

Input
The first line contains a single integer 𝑛 (2≤𝑛≤105) — the initial length of the array.

The second line contains 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤109) — the elements of the array. It is guaranteed that 𝑎𝑖≤𝑎𝑖+1 for all 1≤𝑖<𝑛.

Output
Print a single integer — the minimum number of steps needed. If there is no solution, print −1.

Examples
inputCopy
4
2 5 6 8
outputCopy
1
inputCopy
3
1 2 3
outputCopy
-1
inputCopy
5
1 2 4 6 20
outputCopy
2
Note
In the first example you can select 2 and 5 and the array becomes [7,6,8].

In the second example you can only obtain arrays [1,1], [3,3] and [0] which are all non-decreasing.

In the third example you can select 1 and 2 and the array becomes [3,4,6,20]. Then you can, for example, select 3 and 4 and the array becomes [7,6,20], which is no longer non-decreasing.

题意分析:

这个题目重点就在于,需要有连续三个数字二进制最高位相同。这样可以形成一个凹,答案就是1,这一个部分剪枝后。n最大只有60左右,直接暴力所有情况,min一下。

代码:

#include <iostream>
#include <algorithm>
#include <iomanip>

using namespace std;
typedef long long ll;
const ll N = 1000005;
int a[N];

int geth(int x)
//看看最高位
{
    int cnt = 0;
    while (x) {
        cnt++;
        x >>= 1;
    }
    return cnt;
}

int dp[100][100];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 3; i <= n; i++) {
        if (geth(a[i]) == geth(a[i - 1]) && geth(a[i]) == geth(a[i - 2]))
        //连续三个数字最高位一样输出1;
        {
            cout << 1 << endl;
            return 0;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j++) {
            int ans = 0;
            for (int k = i; k <= j; k++)
                ans ^= a[k];
            //&(与运算)、|(或运算)、^(异或运算)
            //草我知道了,我自己写的时候写的是&。
            //气死我了!!!!
            dp[i][j] = ans;
            //i~j间的数字异或最多异或到ans
        }
    }
    int mmin = 0x3f3f3f3f;
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            for (int k = i; k < j; k++) {
                if (dp[i][k] > dp[k + 1][j])
   //合并i~k,k+1~j,前者比后者大,破坏了非递减性。
                {
                    mmin = min(mmin, j - i - 1);
                }
            }
        }
    }
    if (mmin == 0x3f3f3f3f) cout << -1 << endl;
    else cout << mmin << endl;
}

我的注释应该写的很清楚了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值