论乱搞的艺术(突然想皮一把)

LuoguP2397yyy loves Maths VI (mode)

大家有其他方法欢迎留言~


 开始乱搞


 

随机,种子选我的生日。(可以试试诸位的生日行不行)

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,x,p,i;
    srand(20031008);
    scanf("%d",&n);
    int k=rand()%n+1;
    for(i=1;i<=n;i++){
        scanf("%d",&x);
        if(i==k)p=x;
    }
    printf("%d\n",p);
    return 0;
}

留一半玩玩。(这是谁生日你们肯定能猜到)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e6+5;

int a[N];

int main()
{
    srand(20030403);
    int n,i,x,p=0,r;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&x);
        r=rand()%5;
        if(r==3||r==4)
            a[++p]=x;
    }
    sort(a+1,a+p+1);
    int s=0,t=0,ans;
    for(i=1;i<=p+1;i++)
        if(a[i]==a[i-1]){
            ++t;
        }
        else{
            if(t>s)s=t,ans=a[i-1];
            t=1;
        }
    printf("%d",ans);
    return 0;
}

乱分块也可以做?(不是生日!!)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int L=1e3+3;
const int N=1e5+5;

int a[L],b[N];

int main()
{
    srand(20190120);
    int n,i,p=0,q,r;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        r=rand()%L;
        for(q=0;i<=n&&q<=r;q++,i++)
            scanf("%d",&a[q]);
        sort(a+1,a+q+1);
        b[++p]=a[(q+1)/2];
    }
    sort(b+1,b+p+1);
    printf("%d",b[(p+1)/2]);
    return 0;
}

 


 以下保证正确性


 

转为求中位数,保留一半数据。(STL大法好)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e6+5;

int a[N];

int main()
{
    int n,i,j;
    scanf("%d",&n);
    for(i=1;2*i<=n;i++)
        scanf("%d",&a[i]);
    make_heap(a+1,a+i);
    for(j=i;j<=n;j++){
        scanf("%d",&a[i]);
        push_heap(a+1,a+i+1);
        pop_heap(a+1,a+i+1);
    }
    printf("%d",a[1]);
    return 0;
}

按位统计,非答案位不会出现超过半数。(按十进制为处理也未尝不可)

#include<iostream>
#include<cstdio>
using namespace std;
const int D=31;

int s[D][2];

int main()
{
    int n,i,j,x,ans=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&x);
        for(j=0;j<D;j++)
            ++s[j][(x>>j)&1];
    }
    for(j=0;j<D;j++)
        if(2*s[j][1]>n)
            ans|=1<<j;
    printf("%d",ans);
    return 0;
}

哈希一波完事。(其实就是上面的算法改成S进制罢了)

#include<iostream>
#include<cstdio>
using namespace std;
const int S=1e5+5;

int q[S],r[S];

int main()
{
    int n,i,x,aq,ar;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&x);
        ++q[x/S];
        ++r[x%S];
    }
    for(i=0;i<S;i++)
        if(2*q[i]>n)aq=i;
    for(i=0;i<S;i++)
        if(2*r[i]>n)ar=i;
    printf("%d",aq*S+ar);
    return 0;
}

 


下述算法保证复杂度


 

据说叫摩尔投票法。(据说摩尔庄园有投票功能?)

#include<iostream>
#include<cstdio>
using namespace std;

int main()
{
    int n,i,s=0,t=0,x;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&x);
        if(!s)t=x;
        if(x==t)++s;
        else --s;
    }
    printf("%d",t);
    return 0;
}

 

posted @ 2019-06-04 21:54  新时代中国特色OIer  阅读(188)  评论(0编辑  收藏  举报