zoukankan      html  css  js  c++  java
  • NOIP2012题解

    T1Vigenère 密码

    传送门

    题解:字符串模拟

    代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    char k[1010],s[1010],ans[1010];
    int len1,len2;
    int main()
    {
        gets(k);
        gets(s);
        len1=strlen(k);
        len2=strlen(s);
        if(len1<len2)
            for(int i=len1;i<len2;i++)    k[i]=k[i-len1];
        for(int i=0,j;i<len2;i++)
        {
            if(k[i]>='A'&&k[i]<='Z')    j=k[i]-'A';
            if(k[i]>='a'&&k[i]<='z')    j=k[i]-'a';
            ans[i]=s[i]-j;
            if(s[i]>='A'&&s[i]<='Z')
                if(ans[i]<'A')    ans[i]+=26;
            if(s[i]>='a'&&s[i]<='z')
                if(ans[i]<'a')    ans[i]+=26;
        }
        for(int i=0;i<len2;i++)    printf("%c",ans[i]);
        return 0;
    }
    AC

    T2国王游戏

    传送门

    题解:贪心,按左右手乘积排序

    假设最后两个人为i,j.要求最后一个人得分小则满足(sum为i之前所有人左手乘积)

    sum*left[j]/right[i]>sum*left[i]/right[j],式子两边为i,j在最后一个位置时,i/j的得分。

    消去sum,left[j]*right[j]>left[i]*right[i],也就是最后一个人得分比前一个人少,必须left*right大。

    从大臣队伍末尾一直推到前面就可以。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 1020
    #define LL long long
    using namespace std;
    
    int n;
    LL ret,cur;
    struct King{
        int l,r,p;
    }a[maxn];
    
    bool cmp(King a,King b){
        return a.p<b.p;
    }
    
    void read(int &x){
        char ch=getchar();x=0;int f=1;
        for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
        x=x*f;
    }
    
    int main(){
    //    freopen("game.in","r",stdin);
    //    freopen("game.out","w",stdout);
        read(n);
        read(a[0].l);read(a[0].r);
        for(int i=1;i<=n;i++){
            read(a[i].l);read(a[i].r);
            a[i].p=a[i].l*a[i].r;
        }
        sort(a+1,a+n+1,cmp);
        cur=a[0].l;
        for(int i=1;i<=n;i++){
            ret=max(ret,cur/a[i].r);
            cur=cur*a[i].l;
        }
        cout<<ret<<endl;
    //    fclose(stdin);fclose(stdout);
        return 0;
    }
    非高精版本

    T3开车旅行

    传送门

    题解:暴力20..为什么每次暴力都是20...

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define LL long long
    #define maxn 1000000
    #define inf 2147483647
    using namespace std;
    
    int n,m,s,cur,h[maxn],dis[maxn][3],v[maxn][3];
    LL ans,lena,lenb,x0;
    int Dis(int x,int y){int p=h[x]-h[y];return p<0?-p:p;}
    LL min_(LL a,LL b){return a<b?a:b;}
    
    void Start(int st){
        int tmp=st,cnt=1;lena=0,lenb=0;
        for(;cnt;cnt++){
            if(cnt&1){
                if(lena+lenb+dis[st][1]>x0){
                    LL k;
                    if(lenb==0)k=inf;
                    else k=lena/lenb;
                    if(k<ans){
                        ans=k;cur=tmp;
                    }else if(k==ans){
                        if(h[tmp]>h[cur])cur=tmp;
                    }
                    return;
                }
                lena+=dis[st][1];
                st=v[st][1];
            }else {
                if(lena+lenb+dis[st][0]>x0){
                    LL k;
                    if(lenb==0)k=inf;
                    else k=lena/lenb;
                    if(k<ans){
                        ans=k;cur=tmp;
                    }else if(k==ans){
                        if(h[tmp]>h[cur])cur=tmp;
                    }
                    return;
                }
                lenb+=dis[st][0];
                st=v[st][0];
            }
        } 
    }
    
    int main(){
    //    freopen("drive.in","r",stdin);
    //    freopen("drive.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&h[i]);//输入高度 
        memset(dis,0x3f,sizeof(dis)); 
        for(int i=1;i<=n;i++){               //预处理最远和次远 
            for(int j=i+1;j<=n;j++){
                int k=Dis(i,j);
                if(k==dis[i][0]){
                    if(h[j]<h[v[i][0]]){
                        v[i][1]=v[i][0];dis[i][1]=dis[i][0];
                        v[i][0]=j;
                    }
                }else if(k<dis[i][0]){
                    dis[i][1]=dis[i][0];v[i][1]=v[i][0];
                    dis[i][0]=k;v[i][0]=j;
                }else if(k==dis[i][1]){
                    if(h[j]<h[v[i][1]])v[i][1]=j;
                }else if(k<dis[i][1]){
                    dis[i][1]=k;v[i][1]=j;
                }
            }
        }
        scanf("%d",&x0);ans=inf;
        for(int i=1;i<=n;i++)Start(i);
        printf("%d
    ",cur);
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d%lld",&s,&x0);ans=inf;
            Start(s);printf("%lld %lld
    ",lena,lenb);
        }
    //    fclose(stdin);fclose(stdout);
        return 0;
    } 
    AC

    T1同余方程

    传送门

    题解:扩展欧几里得

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define LL long long
    using namespace std;
    
    LL a,b,x,y;
    
    void exgcd(LL a,LL b,LL &x,LL &y){
        if(b==0){
           x=1;y=0;
           return;
        }
        exgcd(b,a%b,x,y);
        LL t=x;x=y;y=t-a/b*y;
    }
    
    int main(){
    //    freopen("mod.in","r",stdin);
    //    freopen("mod.out","w",stdout);
        scanf("%lld%lld",&a,&b);
        exgcd(a,b,x,y);
        printf("%lld
    ",(x+b)%b);
    //    fclose(stdin);fclose(stdout);
        return 0;
    }
    AC

    T2借教室

    传送门

    题解:线段树区间修改和区间最小值

    线段树95..可能我线段树常数略大..

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1000009
    #define inf 1000000009
    using namespace std;
    
    int n,m,s,t,d,flag;
    int w[maxn];
    struct Tree{
        int l,r,mn,s;
    }tr[maxn<<2];
    
    inline void read(int &x){
        char ch=getchar();x=0;int f=1;
        for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
        x=x*f;
    }
    
    void pushdown(int rt){
        if(!tr[rt].s)return;
        tr[rt<<1].s+=tr[rt].s;tr[rt<<1|1].s+=tr[rt].s;
        tr[rt<<1].mn-=tr[rt].s;tr[rt<<1|1].mn-=tr[rt].s;
        tr[rt].s=0;return;
    }
    
    void pushup(int rt){
        tr[rt].mn=min(tr[rt<<1].mn,tr[rt<<1|1].mn);
        return;
    }
    
    void build(int rt,int l,int r){
        tr[rt].l=l;tr[rt].r=r;
        if(l==r){
            tr[rt].mn=w[l];
            return;
        }
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    
    void update(int rt,int l,int r,int ql,int qr,int p){
        if(l>=ql&&r<=qr){
            tr[rt].mn-=p;
            tr[rt].s+=p;
            return;
        }
        int mid=(l+r)>>1;
        if(ql<=mid)update(rt<<1,l,mid,ql,qr,p);
        if(qr>mid)update(rt<<1|1,mid+1,r,ql,qr,p);
        pushup(rt);
    }
    
    int query_mn(int rt,int l,int r,int ql,int qr){
        pushdown(rt);
        if(l>=ql&&r<=qr){
            return tr[rt].mn;
        }
        int ans=inf,mid=(l+r)>>1;
        if(ql<=mid)ans=min(ans,query_mn(rt<<1,l,mid,ql,qr));
        if(qr>mid)ans=min(ans,query_mn(rt<<1|1,mid+1,r,ql,qr));
        return ans;
    }
    
    int main(){
    //    freopen("classroom.in","r",stdin);
    ////    freopen("classroom.out","w",stdout);
        read(n);read(m);
        for(int i=1;i<=n;i++)read(w[i]);
        build(1,1,n);
        for(register int i=1;i<=m;i++){
            read(d);read(s);read(t);
            if(k>=d)update(1,1,n,s,t,d);
            else {
                printf("-1
    ");
                printf("%d
    ",i);
                return 0;
            }
        }
            puts("0");
    //    fclose(stdin);fclose(stdout);
        return 0;
    }
    AC

    T3疫情控制

    传送门

  • 相关阅读:
    Array总结
    js 添加收藏
    js 浮点数
    chrome 不支持 input file cursor:pointer
    nginx proxy_set_header设置、自定义header
    docker常用命令
    ssh登录问题解决
    android10 搜索不到ble设备的问题解决
    go语言接口型函数使用
    树莓派gpio驱动
  • 原文地址:https://www.cnblogs.com/zzyh/p/7698970.html
Copyright © 2011-2022 走看看