• 考试题玄学解法


    以下是题目
    “与”
    (and.pas/.c/.cpp)
    【题目描述】
    数学大神HYY又开始发威了,他随口给出一道题:有一个长度为n的序列A,请你求出一对Ai,Aj(1<=i<j<=n)使Ai“与”Aj的值最大。
    Ps:“与”表示位运算and,在c++中表示为&。
    【输入描述】
    第一行为n。接下来n行,一行一个整数表示Ai。
    【输出描述】
    输出最大的Ai“与”Aj的结果。
    【样例输入】
    3
    8
    10
    2
    【样例输出】
    8
    【样例解释】
    8 and 10 = 8
    8 and 2 = 0
    10 and 2 = 2
    【数据范围】
    20%的数据保证n<=5000
    100%的数据保证 n<=3*105,0<=Ai<=109


    玄学贪心跑过正解,一直被人卡,从未被卡掉
    要AC只需要贪心前三个高位1即可
    同学的毒瘤数据逼着我贪到了第9个.......

    #include<cstdio>
    #include<cstring>
    #define N 300005
    #define inf 0x7f7f7f7f
    //ÐþѧËã·¨µÈÄãÀ´¿¨ 
    using namespace std;
    
    inline int read(){
        int e=0,ch=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')ch=-1;c=getchar();}
        while(c>='0'&&c<='9'){e=e*10+(c-48);c=getchar();}
        return e*ch;
    }
    
    int n,cnt,minn=inf,minn2=inf,minn3=inf,minn4=inf,minn5=inf,minn6=inf,minn7=inf,minn8=inf,minn9=inf,ans;
    int a[N],c[N],d[N];
    bool key=0;
    
    inline int max(int x,int y){
        if(x>y) return x;
        return y;
    }
    
    inline void uper4(int x){
        int l=0,k=a[x];
        if(k==0) l=100000;
        while(k>0){
            k<<=1;
            l++;
        }
        if(l>minn) return;
        k<<=1;int l2=0;
        if(k==0) l2=100000;
        while(k>0){
            k<<=1;
            l2++;
        }
        k<<=1;int l3=0;
        if(k==0) l3=100000;
        while(k>0){
            k<<=1;
            l3++;
        }
        k<<=1;int l4=0;
        if(k==0) l4=100000;
        while(k>0){
            k<<=1;
            l4++;
        }
        if(l<minn){
            minn=l;
            minn2=l2;
            minn3=l3;
            minn4=l4;
            cnt=1;
            c[cnt]=a[x];
            d[cnt]=x;
            return;
        }
        else if(l==minn){
            if(l2>minn2) return;
            if(l2==minn2){
                if(l3>minn3) return;
                if(l3==minn3){
                    if(l4>minn4) return;
                    if(l4==minn4){
                        c[++cnt]=a[x];
                        d[cnt]=x;
                    }
                    else{
                        minn4=l4;
                        cnt=1;
                        c[cnt]=a[x];
                        d[cnt]=x;
                    }
                }
                else if(l3<minn3){
                    minn3=l3;
                    minn4=l4;
                    cnt=1;
                    c[cnt]=a[x];
                    d[cnt]=x;
                }
            }
            else{
                minn2=l2;
                minn3=l3;
                minn4=l4;
                cnt=1;
                c[cnt]=a[x];
                d[cnt]=x;
            }
            return;
        }
    }
    
    inline void uper6(int x){
    	int l=0,k=a[x];
    	if(k==0) l=100000;
    	while(k>0){
    		k<<=1;
    		l++;
    	}
    	if(l>minn) return;
    	k<<=1;int l2=0;
    	if(k==0) l2=100000;
    	while(k>0){
    		k<<=1;
    		l2++;
    	}
    	k<<=1;int l3=0;
    	if(k==0) l3=100000;
    	while(k>0){
    		k<<=1;
    		l3++;
    	}
    	k<<=1;int l4=0;
    	if(k==0) l4=100000;
    	while(k>0){
    		k<<=1;
    		l4++;
    	}
    	k<<=1;int l5=0;
    	if(k==0) l5=100000;
    	while(k>0){
    		k<<=1;
    		l5++;
    	}
    	k<<=1;int l6=0;
    	if(k==0) l6=100000;
    	while(k>0){
    		k<<=1;
    		l6++;
    	}
    	if(l<minn){
    		minn=l;
    		minn2=l2;
    		minn3=l3;
    		minn4=l4;
    		minn5=l5;
    		minn6=l6;
    		cnt=1;
    		c[cnt]=a[x];
    		d[cnt]=x;
    		return;
    	}
    	else if(l==minn){
    		if(l2>minn2) return;
    		if(l2==minn2){
    			if(l3>minn3) return;
    			if(l3==minn3){
    				if(l4>minn4) return;
    				if(l4==minn4){
    					if(l5>minn5) return;
    					if(l5==minn5){
    						if(l6>minn6) return;
    						if(l6==minn6){
    							c[++cnt]=a[x];
    							d[cnt]=x;
    						}
    						else{
    							minn6=l6;
    							cnt=1;
    							c[cnt]=a[x];
    							d[cnt]=x;
    						}
    					}
    					else{
    						minn5=l5;
    						minn6=l6;
    						cnt=1;
    						c[cnt]=a[x];
    						d[cnt]=x;
    					}
    				}
    				else{
    					minn4=l4;
    					minn5=l5;
    					minn6=l6;
    					cnt=1;
    					c[cnt]=a[x];
    					d[cnt]=x;
    				}
    			}
    			else if(l3<minn3){
    				minn3=l3;
    				minn4=l4;
    				minn5=l5;
    				minn6=l6;
    				cnt=1;
    				c[cnt]=a[x];
    				d[cnt]=x;
    			}
    		}
    		else{
    			minn2=l2;
    			minn3=l3;
    			minn4=l4;
    			minn5=l5;
    			minn6=l6;
    			cnt=1;
    			c[cnt]=a[x];
    			d[cnt]=x;
    		}
    		return;
    	}
    }
    
    inline void uper9(int x){
    	int l=0,k=a[x];
    	if(k==0) l=100000;
    	while(k>0){
    		k<<=1;
    		l++;
    	}
    	if(l>minn) return;
    	k<<=1;int l2=0;
    	if(k==0) l2=100000;
    	while(k>0){
    		k<<=1;
    		l2++;
    	}
    	k<<=1;int l3=0;
    	if(k==0) l3=100000;
    	while(k>0){
    		k<<=1;
    		l3++;
    	}
    	k<<=1;int l4=0;
    	if(k==0) l4=100000;
    	while(k>0){
    		k<<=1;
    		l4++;
    	}
    	k<<=1;int l5=0;
    	if(k==0) l5=100000;
    	while(k>0){
    		k<<=1;
    		l5++;
    	}
    	k<<=1;int l6=0;
    	if(k==0) l6=100000;
    	while(k>0){
    		k<<=1;
    		l6++;
    	}
    	k<<=1;int l7=0;
    	if(k==0) l7=100000;
    	while(k>0){
    		k<<=1;
    		l7++;
    	}
    	k<<=1;int l8=0;
    	if(k==0) l8=100000;
    	while(k>0){
    		k<<=1;
    		l8++;
    	}
    	k<<=1;int l9=0;
    	if(k==0) l9=100000;
    	while(k>0){
    		k<<=1;
    		l8++;
    	}
    	if(l<minn){
    		minn=l;
    		minn2=l2;
    		minn3=l3;
    		minn4=l4;
    		minn5=l5;
    		minn6=l6;
    		minn7=l7;
    		cnt=1;
    		c[cnt]=a[x];
    		d[cnt]=x;
    		return;
    	}
    	else if(l==minn){
    		if(l2>minn2) return;
    		if(l2==minn2){
    			if(l3>minn3) return;
    			if(l3==minn3){
    				if(l4>minn4) return;
    				if(l4==minn4){
    					if(l5>minn5) return;
    					if(l5==minn5){
    						if(l6>minn6) return;
    						if(l6==minn6){
    							if(l7>minn7) return;
    							if(l7<minn7){
    								if(l8>minn8) return;
    								if(l8==minn8){
    									if(l9>minn9) return;
    									if(l9==minn9){
    										c[++cnt]=a[x];
    										d[cnt]=x;
    									}
    									else{
    										minn9=l9;
    										cnt=1;
    										c[cnt]=a[x];
    										d[cnt]=x;
    									}
    								}
    								minn8=l8;
    								minn9=l9;
    								cnt=1;
    								c[cnt]=a[x];
    								d[cnt]=x;
    							}
    							else{
    								minn7=l7;
    								minn8=l8;
    								minn9=l9;
    								cnt=1;
    								c[cnt]=a[x];
    								d[cnt]=x;
    							}
    						}
    						else{
    							minn6=l6;
    							minn7=l7;
    							minn8=l8;
    							minn9=l9;
    							cnt=1;
    							c[cnt]=a[x];
    							d[cnt]=x;
    						}
    					}
    					else{
    						minn5=l5;
    						minn6=l6;
    						minn7=l7;
    						minn8=l8;
    						minn9=l9;
    						cnt=1;
    						c[cnt]=a[x];
    						d[cnt]=x;
    					}
    				}
    				else{
    					minn4=l4;
    					minn5=l5;
    					minn6=l6;
    					minn7=l7;
    					minn8=l8;
    					minn9=l9;
    					cnt=1;
    					c[cnt]=a[x];
    					d[cnt]=x;
    				}
    			}
    			else{
    				minn3=l3;
    				minn4=l4;
    				minn5=l5;
    				minn6=l6;
    				minn7=l7;
    				minn8=l8;
    				minn9=l9;
    				cnt=1;
    				c[cnt]=a[x];
    				d[cnt]=x;
    			}
    		}
    		else{
    			minn2=l2;
    			minn3=l3;
    			minn4=l4;
    			minn5=l5;
    			minn6=l6;
    			minn7=l7;
    			minn8=l8;
    			minn9=l9;
    			cnt=1;
    			c[cnt]=a[x];
    			d[cnt]=x;
    		}
    		return;
    	}
    }
    
    int main(){
    	freopen("data.in","r",stdin);
    //	freopen("and.out","w",stdout);
        n=read();
        for(register int i=1;i<=n;++i){
            a[i]=read();if(a[i]!=a[i-1]&&i!=1) key=1;
        }
        if(!key){
            printf("%d",a[1]);return 0;
        }
        if(n<=100005) for(register int i=1;i<=n;++i) uper4(i);//根据不同数据级别选择不同贪心精度,否则会T
        else if(n<=2750001) for(register int i=1;i<=n;++i) uper6(i);
        else for(register int i=1;i<=n;++i) uper9(i);
        if(cnt==1){//防止被小数据卡
            for(int i=1;i<=n;++i){
                for(int j=i+1;j<=n;++j){
                    ans=max(ans,a[i]&a[j]);
                }
            }
        }
        else{
            for(register int i=1;i<=cnt;++i){
                for(register int j=i+1;j<=cnt;++j){
                    ans=max(ans,c[i]&c[j]);
                }
            }
        }
        printf("%d",ans);
        return 0;
    }
    

    以下是当晚改进的版本

    #include<cstdio>
    #include<cstring>
    #define N 300005
    #define inf 0x7f7f7f7f
    using namespace std;
    
    inline int read(){
        int e=0,ch=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')ch=-1;c=getchar();}
        while(c>='0'&&c<='9'){e=e*10+(c-48);c=getchar();}
        return e*ch;
    }
    
    int n,cnt,ans,jie;
    int minn[N],l[N];
    int a[N],c[N],d[N];
    bool key=0;
    
    inline int max(int x,int y){
        if(x>y) return x;
        return y;
    }
    
    inline void uper(int x){
    	int num=1,k=a[x];
    	memset(l,0,sizeof l);
    	while(num<=jie){
    		if(k==0){
    			for(int i=num;i<=jie;++i) l[i]=10000;
    		}
    		while(k>0){
    			k<<=1;
    			l[num]++;
    		}
    		if(l[num]>minn[num]) return;
    		k<<=1;
    		num++;
    	}
    	num=1;
    	while(num<=jie){
    		if(l[num]>minn[num]) return;
    		if(l[num]<minn[num]){
    			for(int i=1;i<=jie;++i){
    				minn[num]=l[num];
    			}
    			cnt=1;
    			c[cnt]=a[x];
    			d[cnt]=x;
    			return;
    		}
    		num++;
    	}
    	c[++cnt]=a[x];
    	d[cnt]=x;
    }
    
    void init(){
    	memset(minn,inf,sizeof minn);
    }
    
    int main(){
    	freopen("and.in","r",stdin);
    	freopen("and.out","w",stdout);
        n=read();
        for(register int i=1;i<=n;++i){
            a[i]=read();if(a[i]!=a[i-1]&&i!=1) key=1;
        }
        if(!key){
            printf("%d",a[1]);return 0;
        }
        if(n<=1000) jie=0;
    	if(n<=100000) jie=3;
    	else if(n<=275001) jie=4;
    	else jie=5;
    	init();
        if(jie^0) for(int i=1;i<=n;++i) uper(i);
        if(cnt==1||jie==0){
            for(register int i=1;i<=n;++i){
                for(register int j=i+1;j<=n;++j){
                    ans=max(ans,a[i]&a[j]);
                }
            }
        }
        else{
            for(register int i=1;i<=cnt;++i){
                for(register int j=i+1;j<=cnt;++j){
                    ans=max(ans,c[i]&c[j]);
                }
            }
        }
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    第二次作业
    《自动化技术中的进给电气传动》读书笔记1.1-1.2
    证券投资分析
    微信官方文档概述
    联想拯救者Y7000电池无法充电问题
    Ubuntu用户权限管理
    证券市场基础知识
    Markdown All in One使用教程
    Markdown学习笔记
    第九周
  • 原文地址:https://www.cnblogs.com/Makerz/p/9430816.html
Copyright © 2020-2023  润新知