zoukankan      html  css  js  c++  java
  • 10.16模拟赛

    T1

    思路1
    STL中的nth_element()方法的使用
    通过调用nth_element(start, start+n, end)
    可以使第n大元素处于第n位置(从0开始,其位置是下标为 n的元素)
    并且比这个元素小的元素都排在这个元素之前
    比这个元素大的元素都排在这个元素之后
    但不能保证他们是有序的

    代码1

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define mod 1000000000
    using namespace std;
    void read(long long &now){
        now=0;bool flag=false;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')flag=true;
            c=getchar();
        }
        while(c>='0'&&c<= '9'){
            now=now*10+c-'0';
            c=getchar();
        }
        now=flag?-now:now;
    }
    inline void putout(long long x){
        char c[15];int k=0;
        if(x<0) putchar('-'),x=-x;
        do{
            c[++k]=x%10+48;
            x/=10;
        }while(x);
        while(k) putchar(c[k--]);
    }
    long long n,m,x,y,a[10000005];
    long long ans;
    int main(){
        freopen("shop.in","r",stdin);
        freopen("shop.out","w",stdout);
        read(n);read(m);
        read(x);read(y);
        a[1]=x;
        for(int i=2;i<=n;i++){
            a[i]=(a[i-1]*y+x)%mod;
        }
        nth_element(a+1,a+m+1,a+n+1);
        for(int i=1;i<=m;i++)ans+=a[i];
        putout(ans);
        return 0;
    }

    思路2
    优先队列(堆)
    由于维护的堆元素元素较少(m<=100)
    时间复杂度n*logm
    而不是n*logn

    代码2

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define mod 1000000000
    using namespace std;
    void read(int &now){
        now=0;bool flag=false;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')flag=true;
            c=getchar();
        }
        while(c>='0'&&c<= '9'){
            now=now*10+c-'0';
            c=getchar();
        }
        now=flag?-now:now;
    }
    inline void putout(long long x){
        char c[15];int k=0;
        if(x<0) putchar('-'),x=-x;
        do{
            c[++k]=x%10+48;
            x/=10;
        }while(x);
        while(k) putchar(c[k--]);
    }
    int n,m,x,y;
    priority_queue<int>q;
    int main(){
        freopen("shop.in","r",stdin);
        freopen("shop.out","w",stdout);
        read(n);read(m);read(x);read(y);
        int now=x;
        q.push(x);
        for(int i=2;i<=n;i++){
            now=(1ll*now*y+x)%mod;
            if(q.size()<m){
                q.push(now);
                continue;
            }
            if(now<q.top()){
                q.pop();
                q.push(now);
            }
        }
        long long ans=0;
        while(!q.empty()){
            ans+=q.top();
            q.pop();
        }
        putout(ans);
        printf("
    ");
        return 0;
    }

    思路3
    是个AC概率极大,但可能答案不对的想法,也是个很奇妙的想法
    可以开数组记录哪些数出现过,并且记录出现过几次(因为可能有重复),然后从小处找够m个
    这种思路我压根没想到
    向来考虑的都是正确的做法,并想方设法证明正确性,而忽略了贪心策略
    这是考试中的一大失误

    代码3

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int N=1e7+1,mod=1e9,M=1e8+1;
    int n,m,emp,a[N],vis[M];
    long long x,y,ans;
    int main() {
        freopen("shop.in","r",stdin);
        freopen("shop.out","w",stdout);
        scanf("%d%d%I64d%I64d",&n,&m,&x,&y);
        a[1]=x;
        if(x<M)vis[x]=1;
        for(int i=2; i<=n; ++i) {
            a[i]=(y*a[i-1]+x)%mod;
            if(a[i]<M)
                ++emp,++vis[a[i]];
        }
        if(n<=1000){
            for(int i=2;i<=n;i++){
                a[i]=(a[i-1]*y+x)%mod;
            }
            sort(a+1,a+n+1);
            for(int i=1;i<=m;i++) ans+=a[i];
        }else{
            if(emp<m){
                sort(a+1,a+n+1);
            }
            for(int i=0; i<M; ++i)
                if(vis[i]) {
                    if(m>vis[i]) {
                        ans+=1ll*i*vis[i];
                        m-=vis[i];
                    } else {
                        ans+=1ll*m*i;
                        break;
                    }
                }
        }
        printf("%I64d",ans);    
        return 0;
    }

    T2

    思路
    Dp

    P[i][j][0]确定第i个是否消失后,二进制第j位是0的概率
    P[i][j][1]确定第i个是否消失后,二进制第j位是1的概率

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define N 100005
    using namespace std;
    int a[N],b[N];
    double c[N];
    int f[N][33];
    double p[N][33][2];
    int n;
    void change(){
        for(int i=1;i<=n;i++){
            int now=b[i];
            int cnt=0;
            while(now){
                f[i][++cnt]=now%2;
                now/=2;
            }
        }
    }
    int main(){
        freopen("exp.in","r",stdin);
        freopen("exp.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int j=1;j<=n;j++) scanf("%d",&b[j]);
        for(int i=1;i<=n;i++) scanf("%lf",&c[i]);
        change();
        for(int i=1;i<=31;i++){
            p[0][i][0]=1;
            p[0][i][1]=0;
        }
        for(int j=1;j<=31;j++){
            for(int i=1;i<=n;i++){
                if(a[i]==0){
                    p[i][j][0]=f[i][j]?(p[i-1][j][0]):(p[i-1][j][1]*(1.0-c[i])+p[i-1][j][0]);
                    p[i][j][1]=f[i][j]?(p[i-1][j][1]):(p[i-1][j][1]*c[i]);
                }else if(a[i]==1){
                    p[i][j][0]=f[i][j]?(p[i-1][j][0]*c[i]):p[i-1][j][0];
                    p[i][j][1]=f[i][j]?(p[i-1][j][1]*c[i]+(1.0-c[i])):p[i-1][j][1];
                }else if(a[i]==2){
                    p[i][j][0]=f[i][j]?(p[i-1][j][1]*(1.0-c[i])+p[i-1][j][0]*c[i]):(p[i-1][j][0]);
                    p[i][j][1]=f[i][j]?(p[i-1][j][0]*(1.0-c[i])+p[i-1][j][1]*c[i]):(p[i-1][j][1]);
                }
            }
        }
        double answer=0.0;
        for(int i=31;i>=1;i--){
            answer=answer*2.0+p[n][i][1];
        }
        printf("%.1f
    ",answer);
        return 0;
    }

    这里有更简洁的做法

    https://www.cnblogs.com/L-Memory/p/9799878.html

  • 相关阅读:
    python并发编程之IO模型
    协程与concurent.furtrue实现线程池与进程池
    网络编程之线程进阶
    多线程讲解
    网络编程之进阶2
    网络编程之进阶
    网络编程之进程
    函数复习之2
    函数复习
    深克隆和浅克隆
  • 原文地址:https://www.cnblogs.com/aptx--4869/p/9801776.html
Copyright © 2011-2022 走看看