考试题玄学解法

以下是题目
“与”
(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;
}
posted @ 2018-08-06 16:08  Makerz  阅读(782)  评论(1编辑  收藏  举报