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;
}
我的注释应该写的很清楚了。