zoukankan      html  css  js  c++  java
  • 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛

    A. Death is end

    留坑

    B.Goldbach

    题意

    每次给一个偶数(n(n<2<2^{63})),找出任意两个和为(n)的素数。

    分析

    从n的(frac{1}{2})往两边判素数,使用Miller Rabin随机性素数测试方法。
    (ps:自己写了一个虽然过了,但是会被Carmichael数卡掉,还没搞懂板子上的算法怎么搞定Carmichael数的,留坑)

    代码 ```cpp #include #include #include #include #include #include #include using namespace std; typedef long long ll; const ll MOD=1e9+7; const int maxn=1000500; struct Miller_Rabin { int prime[5]={2,3,5,233,331}; ll qmul(ll x,ll y,ll mod){ ll ans=(x*y-(ll)((long double)x/mod*y+1e-3)*mod); ans=(ans%mod+mod)%mod; return ans; } ll qpow(ll x,ll n,ll mod){ ll ans=1; while(n){ if(n&1) ans=qmul(ans,x,mod); x=qmul(x,x,mod); n>>=1; } return ans; } bool isprime_std(ll p) { if(p < 2) return 0; if(p != 2 && p % 2 == 0) return 0; ll s = p - 1; while(! (s & 1)) s >>= 1; for(int i = 0; i < 5; ++i) { if(p == prime[i]) return 1; ll t = s, m = qpow(prime[i], s, p); while(t != p - 1 && m != 1 && m != p - 1) { m = qmul(m, m, p); t <<= 1; } if(m != p - 1 && !(t & 1)) return 0; } return 1; } bool isprime(ll p){ if(p<2||(p!=2&&p%2==0)) return false; for (int i = 0; i < 5; ++i) { if(p==prime[i]) return true; ll t=qpow(prime[i],p-1,p); if(t!=1) return false; } return true; } }mr; int main(int argc, char const *argv[]) { ll x; while(cin>>x){ printf("%d %d ", mr.isprime(x),mr.isprime_std(x)); } int t; scanf("%d", &t); while(t--){ ll x; scanf("%lld", &x); if(x==4){ printf("2 2 "); continue; } ll mid=x/2; if(!(mid&1)) mid--; for (ll i = mid; i >= 0; i-=2) { if(mr.isprime_std(i)&&mr.isprime_std(x-i)){ printf("%lld %lld ", i,x-i); break; } } } return 0; } ```

    C. Heru and his Monitors

    又要留坑-_-|||

    D. Merchandise

    分析

    筛选出素数之后,显然同样大小素数不能分在多个组里,否则无法达到最优。
    使用(dp[i][j])表示前(i)个素数分成(j)组的最小总花费,那么可以得到转移方程

    [dp[i][j]=min(dp[k-1][j-1]+(a[i]-a[k])^2), (1<=k<=i) ]

    (ps: 强烈谴责计蒜客的数据,交题的时候必须把(0,1)作为素数,否则就会像我一样浪费两天时间)

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <map>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll MOD=1e9+7;
    const int maxn=10500;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    bool isprime[1<<17];
    void get_prime(){
        memset(isprime,true,sizeof isprime);
        // isprime[0]=isprime[1]=false;
        int n=(1<<17);
        for (int i = 2; i < n; ++i)
        {
            if(isprime[i]&&(double)i<=sqrt(n)+1){
                for (int j = i*i; j < n; j+=i)
                {
                    isprime[j]=false;
                }
            }
        }
    }
    ll a[100050],dp[5050][1050];
    int q[7050];
    double f[7050];
    int main(int argc, char const *argv[])
    {
        get_prime();
        int t;
        scanf("%d", &t);
        while(t--){
            int r,m;
            scanf("%d%d", &r,&m);
            int n=0;
            for (int i = 0; i < r; ++i)
            {
                int x;
                scanf("%d",&x);
                if(isprime[x]) a[n++]=x;
            }
            sort(a,a+n);
            n=unique(a,a+n)-a;
            for (int i = n; i ; --i)
            {
                a[i]=a[i-1];
            }
            for (int j = 1; j <= m; ++j) dp[0][j]=inf;
            for (int i = 0; i <= n; ++i) dp[i][0]=inf;
            for (int j = 1; j <= m; ++j)
            {
                int h=1,t=0;
                for (int i = 1; i <= n; ++i)
                {
                    if(j==1){
                        dp[i][j]=(a[i]-a[1])*(a[i]-a[1]);
                        continue;
                    }
                    int k=q[t];
                    double ff=(double)(dp[i-1][j-1]-dp[k-1][j-1]+a[i]*a[i]-a[k]*a[k])/double(a[i]-a[k]);
                    while(t-h+1>=2&&ff<f[t]){
                        t--;
                        k=q[t];
                        ff=(double)(dp[i-1][j-1]-dp[k-1][j-1]+a[i]*a[i]-a[k]*a[k])/double(a[i]-a[k]);
                    }
                    ++t;
                    q[t]=i;
                    f[t]=ff;
    
                    while(t-h+1>=2&&(double)2*a[i]>f[h+1]){
                        h++;
                    }
                    k=q[h];
                    dp[i][j]=dp[k-1][j-1]+(a[i]-a[k])*(a[i]-a[k]);
                }
            }
            printf("%lld
    ", dp[n][m]);
        }
        return 0;
    }
    

    E. Copy and Submit II

    太水了略

    F. Clever King

    (color{red}{留坑})

    G. Trouble of Tyrant

    H. Rock Paper Scissors Lizard Spock

    I. Reversion Count

    J. Bob's game

    K. Ants

    L. Nise-Anti-AK Problem

    Click to expand whatever
    html
    
  • 相关阅读:
    C#异步编程由浅入深(一)
    基于Jira的运维发布平台的设计与实现
    kubeadm部署K8S并使用containerd做运行时
    代码阅读
    黑客攻防 1
    Linux 常用指令篇1
    期刊管理系统总结
    docker安装RabbitMQ
    Centos7安装mysql8.0教程
    java动态编译
  • 原文地址:https://www.cnblogs.com/sciorz/p/8922873.html
Copyright © 2011-2022 走看看