标签:and double efi span log lag nbsp getch for
【题目描述】
给定 n 个数,找出两个,使得它们经过与运算后结果最大。
注意,选出来的两个数在原数组中的位置不能一样,但是数值可以一样。
【输入格式】
第一行一个整数 n,表示数字个数。
第二行 n 个数,表示给定的数。
【输出格式】
一个整数表示答案。
【样例输入】
3
1 2 1
【样例输出】
1
【数据范围】
对于 20%的数据点,n <= 1000
对于另外 20%的数据点,只有 0 和 1
对于 100%的数据点,n <= 100000, 0 <= 数值 <= 10^9
我们知道当当前位都是1时与出来才是1,所以我们考虑从位数高的地方开始统计。
如果当前位数字数量大于2,那么就符合条件,然后递归继续找低位有没有满足条件的。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define il inline
#define db double
using namespace std;
il int gi()
{
int x=0,y=1;
char ch=getchar();
while(ch<‘0‘||ch>‘9‘)
{
if(ch==‘-‘)
y=-1;
ch=getchar();
}
while(ch>=‘0‘&&ch<=‘9‘)
{
x=x*10+ch-‘0‘;
ch=getchar();
}
return x*y;
}
int point[100045];
int stackk[100045];
int stack[100045];
int ci[45];
int num[31][100005];
int s[31];
int er[100005][31];
int check(int now,int tot)//now是当前2的几次方,tot是有多少数满足
{
//printf("now=%d tot=%d\n",now,tot);
if(now==0)
return 1;
for(int next=1;now-next>=0;next++)
{
int cnt=0;
for(int i=1;i<=tot;i++)
if(er[stack[i]][now-next])
stackk[++cnt]=stack[i];
if(cnt>=2)
{
for(int i=1;i<=cnt;i++)
stack[i]=stackk[i];
return ci[now]+check(now-next,cnt);
}
}
return ci[now];
}
int main()
{
freopen("and.in","r",stdin);
freopen("and.out","w",stdout);
int n=gi();
ci[0]=1;
for(int i=1;i<=30;i++)
ci[i]=ci[i-1]*2;
int x;
bool flag=0;
for(int i=1;i<=n;i++)
{
x=gi();
if(x!=0)
flag=1;
point[i]=x;
for(int j=30;j>=0;j--)
if(x>=ci[j])
{
x-=ci[j];
er[i][j]=1;
num[j][++s[j]]=i;
}
}
int now=30;
while(s[now]<2&&now>=0)
{
now--;
}
for(int i=1;i<=s[now];i++)
stack[i]=num[now][i];
if(flag)
printf("%d\n",check(now,s[now]));
else
printf("0\n");
return 0;
}
标签:and double efi span log lag nbsp getch for
原文地址:http://www.cnblogs.com/gshdyjz/p/7700075.html