zoukankan      html  css  js  c++  java
  • 与运算 递归

    【题目描述】
    给定 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
    ",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
    ",check(now,s[now]));
    	else
    		printf("0
    ");
    
    	return 0;
    }
    
  • 相关阅读:
    Java基础语法(11)-面向对象之关键字
    Java基础语法(10)-面向对象之三大特征
    Java基础语法(9)-面向对象之类的成员
    Java基础语法(8)-数组中的常见排序算法
    Java基础语法(7)-数组
    Java基础语法(6)-注释
    Java基础语法(5)-特殊流程控制语句
    Java基础语法(4)-流程控制
    Java基础语法(3)-运算符
    sunset: dawn
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7700075.html
Copyright © 2011-2022 走看看