标签:p2 p1 ai max Underscores Codeforces Evil int include
题意:
有一个长度为 n (1≤n≤105)的整数序列 a1,⋯,an (0≤ai≤230−1),你需要找到一个非负整数 X 使得 max(ai⊕X)最小,其中 ⊕ 为按位异或运算。
输入这个序列,输出max(ai⊕X)的最小值。
思路:
1.数组中的每个数的二进制下的某位(第k位)都是0或者是1,那么x的第k位取值是0或者1,使得答案中的第k位一定是0(这样得到的结果才会更小)。
2.数组中的每个数的二进制下的某位(第k位)有1又有0,不管x的第k位取得0或1,异或后的结果都是1(因为我们找的是max(ai⊕X),只要有1肯定要算)。所得答案的第k位一定是1,然后取最小的值对于剩下的k-1位(递归就行)。
代码:
//借鉴了qscqesze大佬的代码,写的很漂亮,我加上了注释
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int MAXN=2e5+50;
const double pi=3.1415926536;
int t,n;
vector<int> a;
int solve(vector<int> p,int k){
if(p.size()==0||k<0)return 0;
vector<int> p1,p2;
for(int i=0;i<p.size();i++){
if((p[i]>>k)&1)p1.push_back(p[i]);//第k位是1的放p1里
else p2.push_back(p[i]);//第k位是0的放p2里
}
if(p1.size()==0)return solve(p2,k-1);//p1里面没元素,说明所有的第k位都是0,答案的第k位为0,只用考虑p2的后面k-1位即可
if(p2.size()==0)return solve(p1,k-1);//p2里面没元素,说明所有的第k位都是1,答案的第k位为0,只用考虑p1的后面k-1位即可
return (1<<k)+min(solve(p1,k-1),solve(p2,k-1));//答案的第k位为1,值为(1<<k),考虑后面k-1位里,p1,p2能够取得的最小值,贪心
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
a.push_back(x);
}
printf("%d\n",solve(a,30));
return 0;
}
Summary
解决的代码类似贪心,但好多大佬说这是字典树模版题,这个代码也用到了字典树的思想,只是不用建树,直接解决的。这个还用用dp写的,意思是树上dp,其实思路差不多,dp的话就是不用递归直接在数组里算出来输出就行.
_Alexander
发布了83 篇原创文章 · 获赞 7 · 访问量 3778
私信
关注
标签:p2,p1,ai,max,Underscores,Codeforces,Evil,int,include 来源: https://blog.csdn.net/weixin_44091178/article/details/104068689
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。