• noip2016 提高组


    T1 玩具谜题 题目传送门

    这道题直接模拟就好了哇 233

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=1e5+7;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,m,k,v,ans=1;
    char s[M][25];
    int h[M];
    int main()
    {
        n=read(); m=read();
        for(int i=1;i<=n;i++) h[i]=read(),scanf("%s",s[i]);//0朝内1朝外 
        for(int i=1;i<=m;i++){
            k=read(); v=read();
            if(!k) v=-v;
            if(h[ans]) v=-v;
            ans=ans+v;
            if(ans<1) ans=ans+n;
            if(ans>n) ans=ans-n; 
        }
        printf("%s",s[ans]);
        return 0;
    }
    View Code

     T2  天天爱跑步 题目传送门

    这道题我 真的 看不懂..... 跳 以后填坑

    T3  换教室  最短路+dp  题目传送门

    这道题是道期望dp f【i】【j】【k】代表到第i个时段换了j个教师k代表当前点换不换(1换0不换) 然后就是一波递推了 

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=2007;
    const double inf=1e15;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,m,v,s,c[M],d[M];
    double k[M],f[M][M][2],dis[M][M],w;
    void prepare(){
        for(int i=1;i<=v;i++)
         for(int j=1;j<=v;j++)
          dis[i][j]=(i==j)?0:inf;
        for(int i=1;i<=n;i++)
         for(int j=0;j<=m;j++)
          f[i][j][0]=f[i][j][1]=inf;
        f[1][0][0]=0; f[1][1][1]=0;
    //    for(int i=1;i<=n;i++,printf("
    ")) for(int j=1;j<=v;j++) printf("[%.2lf %.2lf] ",f[i][j][0],f[i][j][1]);
    }
    void floyd(){
        for(int k=1;k<=v;k++)
         for(int i=1;i<=v;i++)
          for(int j=1;j<=v;j++)
           dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    //    for(int i=1;i<=v;i++,printf("
    ")) for(int j=1;j<=v;j++) printf("%.2lf ",dis[i][j]);
    }
    int main()
    {
        int x,y; 
        n=read(); m=read(); v=read(); s=read();
        for(int i=1;i<=n;i++) c[i]=read();
        for(int i=1;i<=n;i++) d[i]=read();
        for(int i=1;i<=n;i++) scanf("%lf",&k[i]);
        prepare();  
        for(int i=1;i<=s;i++){
            x=read(); y=read(); scanf("%lf",&w); 
            dis[x][y]=dis[y][x]=min(dis[x][y],w); 
        }
        floyd();
        for(int i=2;i<=n;i++){
            for(int j=0;j<=m;j++){
                if(!j) {f[i][j][0]=min(f[i][j][0],f[i-1][j][0]+dis[c[i-1]][c[i]]); continue;}
                f[i][j][0]=min(f[i][j][0],f[i-1][j][0]+dis[c[i-1]][c[i]]);
                f[i][j][0]=min(f[i][j][0],f[i-1][j][1]+dis[d[i-1]][c[i]]*k[i-1]+dis[c[i-1]][c[i]]*(1-k[i-1]));
                f[i][j][1]=min(f[i][j][1],f[i-1][j-1][0]+dis[c[i-1]][d[i]]*k[i]+dis[c[i-1]][c[i]]*(1-k[i]));
                double d1=k[i]*k[i-1]*dis[d[i-1]][d[i]],d2=k[i]*(1-k[i-1])*dis[c[i-1]][d[i]];
                double d3=(1-k[i])*k[i-1]*dis[d[i-1]][c[i]],d4=(1-k[i])*(1-k[i-1])*dis[c[i-1]][c[i]];
                f[i][j][1]=min(f[i][j][1],f[i-1][j-1][1]+d1+d2+d3+d4);
            }
        }
        double ans=inf;
        for(int i=0;i<=m;i++) ans=min(ans,f[n][i][0]),ans=min(ans,f[n][i][1]);
        printf("%.2lf
    ",ans);
        return 0;
    }
    View Code

    T4  组合数问题 题目传送门

    这道题 搜索打一波发现是个类似杨辉三角的东西 然后就维护一波前缀和方便计算就好了哇 其实可以跑两波实现o(1) 查询 不过 我懒啦 233

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int M=2007;
    LL read(){
        LL ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    LL f[M][M],sum[M][M];
    LL n,m,T,k,ans;
    void prepare(){
        for(LL i=0;i<M;i++) f[i][0]=1;
        for(LL i=1;i<M;i++)
         for(LL j=1;j<=i;j++){
             f[i][j]=(f[i-1][j]+f[i-1][j-1])%k;
             if(!f[i][j]) sum[i][j]=1;
             sum[i][j]+=sum[i][j-1];
         }
    }
    int main()
    {
        for(T=read(),k=read(),prepare();T;T--){
            n=read(); m=read(); ans=0;
            for(LL i=1;i<=n;i++) ans=ans+sum[i][min(i,m)];
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

     T5  蚯蚓 题目传送门

    这道题其实就是维护三个队列q1是原队列 按从小到达sort一波 以后都不会有更新了 q2,q3分别储存砍完的前后半段 可以证明两个队列都是单调递减的 然后整体的加转化成个体的减的好了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int M=1e7+7;
    LL read(){
        LL ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    LL n,m,q,u,v,k;
    LL h1=1,h2=1,h3=1,t2,t3;
    LL q1[M],q2[M],q3[M];
    bool cmp(LL a,LL b){return a>b;}
    LL push_max(LL x){
        LL sum=-0x3f3f3f3f3f3f3f3f;
        if(h1<=n) sum=max(sum,q1[h1]);
        if(h2<=t2) sum=max(sum,q2[h2]);
        if(h3<=t3) sum=max(sum,q3[h3]);
        if(h1<=n&&q1[h1]==sum) h1++;
        else if(h2<=t2&&q2[h2]==sum) h2++;
        else h3++;
        //printf("[%lld]
    ",sum+q*(x-1));
        return sum+q*(x-1);
    }
    int main()
    {
        n=read(); m=read(); q=read(); u=read(); v=read(); k=read();
        for(int i=1;i<=n;i++) q1[i]=read();
        sort(q1+1,q1+1+n,cmp);
        //for(int i=1;i<=n;i++) printf("[%d] ",q1[i]);
        for(LL i=1;i<=m;i++){
            LL sum=push_max(i);
            if(i%k==0) printf("%lld ",sum);
            LL now=sum*u/v;
            //printf("[%lld %lld]
    ",now,sum-now);
            q2[++t2]=now-i*q; q3[++t3]=sum-now-i*q;
            
        }printf("
    ");
        for(LL i=1;i<=n+m;i++){
            LL sum=push_max(m+1);
            if(i%k==0) printf("%lld ",sum);
        }
        return 0;
    }
    View Code

     当然优先队列也可以打部分分 但是因为m太大了 nlog(n+m) 会T 只能拿六十分 贴一波T的代码啦

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define LL long long
    using namespace std;
    const int M=1e7+7;
    LL read(){
        LL ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    LL x;
    struct node{
        LL w;
        bool operator < (const node &x)const {return w<x.w;}
    };
    priority_queue<node>qu;
    int n,m,q,u,v,k;
    int main()
    {
        n=read(); m=read(); q=read(); u=read(); v=read(); k=read();
        for(int i=1;i<=n;i++) x=read(),qu.push((node){x});
    //    while(!qu.empty()){node x=qu.top(); printf("%lld
    ",x.w); qu.pop();}
        for(int i=1;i<=m;i++){
            node x=qu.top(); qu.pop();
            LL sum=x.w+(i-1)*q,now=sum*u/v,cur=sum-now;
            qu.push((node){now-i*q});
            qu.push((node){cur-i*q});
            if(i%k==0) printf("%lld ",sum);
        }printf("
    ");
        for(int i=1;i<=n+m;i++){
            node x=qu.top(); qu.pop();
            LL sum=x.w+m*q;
            if(i%k==0) printf("%lld ",sum);
        }
        return 0;
    }
    View Code

     T6 愤怒的小鸟 题目传送门

    这是一道状压dp g【i】【j】表示经过i,j两个点的二次函数一共能经过的点数 

    然后根据这个可以推出一波答案 不过要记得算一只鸟只打死一只猪的情况就好了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int M=25;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int T,n,m;
    int g[M][M],f[1<<M],id[M];
    double x[M],y[M],a,b;
    bool pd(double x,double y){return fabs(x-y)<1e-6;}
    void push_ans(){
        n=read(); m=read();
        for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]);
        memset(g,0,sizeof(g));
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                if(pd(x[i],x[j])) continue;
                a=(y[i]/x[i]-y[j]/x[j])/(x[i]-x[j]);
                if(a>=0) continue;
                b=y[i]/x[i]-a*x[i];
                int sum=0;
                for(int k=1;k<=n;k++) if(pd(a*x[k]+b,y[k]/x[k])) sum+=id[k];
                g[i][j]=sum;
            }
        }
        memset(f,0x3f,sizeof(f));
        f[0]=0;
        for(int k=0;k<(1<<n);k++)
         for(int i=1;i<=n;i++){
            if(id[i]&k) continue;
            for(int j=i+1;j<=n;j++) f[k|g[i][j]]=min(f[k|g[i][j]],f[k]+1);
            f[id[i]|k]=min(f[id[i]|k],f[k]+1);
         }
        printf("%d
    ",f[(1<<n)-1]);
    }
    int main()
    {
        for(int i=1;i<M;i++) id[i]=1<<(i-1);
        for(T=read();T;T--) push_ans();
        return 0;
    }
    View Code
  • 相关阅读:
    520了,用32做个简单的小程序
    年轻就该多尝试,教你20小时Get一项新技能
    自定义注解!绝对是程序员装逼的利器!!
    vs2015添加ActiveX Control Test Container工具(转载)
    编译MapWinGis
    C#遍历集合与移除元素的方法
    c#winform程序,修改MessageBox提示框中按钮的文本
    java程序员面试答题技巧
    什么是DOM
    uml类关系
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7123247.html
Copyright © 2020-2023  润新知