区间或及异或
题意
给你一个数列,让你将其进行等间距拆分成一个或者多个数列,对于每一个数列,计算其中所有数字的或,然后求出以这种方式进行拆分的所有区间的最小的异或值。
- 1<= N <= 20
- 0 <= Ai <= 230
解题思路:
首先,我们看到此题的数据范围非常小,所以我们坚信此题一定可以做出来。由于题目要求等间距拆分,因此我们可以通过递归求解,怎么递归?先递归求每个区间内的或,然后将它们求异或,求出最小值即可。
官方题解
#include <bits / stdc ++。h>
int ri(){
int n;
scanf(“%d”,&n);
返回n;
}
int main(){
int n = ri();
int a [n];
对于(auto&i:a)i = ri();
整数res = 2000000000;
for(int i = 0; i <1 <<(n-1); i ++){
int xored = 0;
整数= 0;
for(int j = 0; j <= n; j ++){
如果(j <n)ored | = a [j];
if(j == n ||(i >> j&1))异或^ = ored,ored = 0;
}
res = std :: min(res,异或);
}
printf(“%d \ n”,res);
返回0;
}
//解法一:
#include<bits/stdc++.h>
using namespace std;
int n,a[30],quj[30][30],ans=(1<<30);
void sous(int now,int nn,int o){
o|=a[now];
if(now==n){ans=min(ans,(nn^o));return ;}
sous(now+1,nn,o);
sous(now+1,(nn^o),0);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
sous(1,0,0);
cout<<ans;
return 0;
}
//解法二:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <math.h>
#include <climits>
#include <iomanip>
#define ll long long
#define ull unsigned long long
using namespace std;
ll N;
ll A[20];
ll ans = 100100100100;
void dfs(int idx, ll OR, ll XOR) {
if (idx == N) {
ans = min(ans, XOR);
return;
}
//OR运算
if (idx < N-1) {
dfs(idx + 1, OR|A[idx], XOR);
}
//XOR运算
dfs(idx + 1, 0, XOR^(OR|A[idx]));
}
int main() {
cin >> N;
for (int i = 0; i < N; ++i) {
cin >> A[i];
}
int idx = 0;
ll OR = 0;
ll XOR = 0;
dfs(idx, OR, XOR);
cout << ans << "\n";
return 0;
}