• noip2017普及题解


    https://www.luogu.org/problemnew/show/3954
    https://www.luogu.org/problemnew/show/3955
    https://www.luogu.org/problemnew/show/3956
    https://www.luogu.org/problemnew/show/3957

    T1

    甚至不想用c++写

    a,b,c=map(int,input().split(' '))
    print((a+a+b+b+b+c+c+c+c+c)//10)
    

    T2

    乱水

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cctype>
    #define rg register
    #define il inline
    #define vd void
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')flg=1;ch=getchar();}
        while(isdigit(ch))x=x*10-'0'+ch,ch=getchar();
        return flg?-x:x;
    }
    int ans[10000001];
    il vd checkmn(int&a,int b){if(b<a)a=b;}
    int main(){
    // 	freopen("librarian.in","r",stdin);
    // 	freopen("librarian.out","w",stdout);
        int n=gi(),orz,q=gi();
        for(rg int i=0;i<10000001;++i)ans[i]=19260817;
        while(n--){
            orz=gi();
            checkmn(ans[orz],orz);
            checkmn(ans[orz%10000000],orz);
            checkmn(ans[orz%1000000],orz);
            checkmn(ans[orz%100000],orz);
            checkmn(ans[orz%10000],orz);
            checkmn(ans[orz%1000],orz);
            checkmn(ans[orz%100],orz);
            checkmn(ans[orz%10],orz);
        }
        for(rg int i=0;i<10000001;++i)if(ans[i]==19260817)ans[i]=-1;
        while(q--)gi(),orz=gi(),printf("%d
    ",ans[orz]);
        return 0;
    }
    

    T3

    dij
    还有BFS/SPFA/DFS/DP...

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #define rg register
    #define il inline
    #define vd void
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')flg=1;ch=getchar();}
        while(isdigit(ch))x=x*10-'0'+ch,ch=getchar();
        return flg?-x:x;
    }
    const int maxn=101;
    int col[maxn][maxn];
    struct orzyyb{int x,y;bool col;};
    int f[maxn][maxn][2];
    bool vis[maxn][maxn][2];
    il bool operator <(const orzyyb&a,const orzyyb&b){return f[a.x][a.y][a.col]>f[b.x][b.y][b.col];}
    std::priority_queue<orzyyb>que;
    const int X[]={0,0,0,1,-1},Y[]={0,1,-1,0,0};
    int main(){
    // 	freopen("chess.in","r",stdin);
    // 	freopen("chess.out","w",stdout);
        int n=gi(),m=gi();
        int x,y,xx,yy,c;
        memset(col,-1,sizeof col);
        memset(f,63,sizeof f);
        while(m--)x=gi(),y=gi(),col[x][y]=gi();
        que.push((orzyyb){1,1,(bool)col[1][1]});
        f[1][1][col[1][1]]=0;
        orzyyb p;
        while(!que.empty()){
            p=que.top();que.pop();
            x=p.x,y=p.y,c=p.col;
            if(vis[x][y][c])continue;
            vis[x][y][c]=1;
            for(rg int i=1;i<5;++i){
                xx=x+X[i],yy=y+Y[i];
                if(xx<1||xx>n||yy<1||yy>n)continue;
                if(~col[xx][yy]){
                    if(f[xx][yy][col[xx][yy]]>f[x][y][c]+(c^col[xx][yy])){
                        f[xx][yy][col[xx][yy]]=f[x][y][c]+(c^col[xx][yy]);
                        que.push((orzyyb){xx,yy,(bool)col[xx][yy]});
                    }
                }else if(~col[x][y]){
                    if(f[xx][yy][0]>f[x][y][c]+(c^0)+2){
                        f[xx][yy][0]=f[x][y][c]+(c^0)+2;
                        que.push((orzyyb){xx,yy,0});
                    }
                    if(f[xx][yy][1]>f[x][y][c]+(c^1)+2){
                        f[xx][yy][1]=f[x][y][c]+(c^1)+2;
                        que.push((orzyyb){xx,yy,1});
                    }				
                }
            }
        }
        int ans=std::min(f[n][n][0],f[n][n][1]);
        if(ans==1061109567)ans=-1;
        printf("%d
    ",ans);
        return 0;
    }
    

    T4

    太套路了

    显然答案单调,所以二分k

    check用动态规划

    一个状态到下一个状态,转移过来的区间会右移(不会左移),所以单调队列优化

    套路的死

    PS.check加个优化快一倍

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cctype>
    #define rg register
    #define il inline
    #define vd void
    typedef int mainint;
    #define int long long
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')flg=1;ch=getchar();}
        while(isdigit(ch))x=x*10-'0'+ch,ch=getchar();
        return flg?-x:x;
    }
    const int maxn=500010;
    int n,x[maxn],s[maxn];
    il bool dp(int l,int r,int k){
        --k;
        static int f[maxn],que[maxn];
        int hd=0,tl=0,q=1,ret=-1e18;
        for(rg int i=1;i<=n;++i){
            while(x[i]-x[q]>=l){
                while((hd^tl)&&f[que[tl-1]]<=f[q])--tl;
                que[tl++]=q++;
            }
            while((hd^tl)&&x[i]-x[que[hd]]>r)++hd;
            if(x[i]>=l&&x[i]<=r)f[i]=s[i];
            else f[i]=-1e18;
            if(hd^tl)f[i]=std::max(f[i],f[que[hd]]+s[i]);
            if(f[i]>k)return 0;
        }
        return 1;
    }
    mainint main(){
    // 	freopen("jump.in","r",stdin);
    // 	freopen("jump.out","w",stdout);
        n=gi();
        int d=gi(),k=gi();
        for(rg int i=1;i<=n;++i)x[i]=gi(),s[i]=gi();
        if(dp(1,x[n],k)){puts("-1");return 0;}
        int l=0,r=x[n],mid;
        while(l<r){
            mid=(l+r)>>1;
            if(dp(std::max(1ll,d-mid),std::min(d+mid,x[n]),k))l=mid+1;
            else r=mid;
        }
        printf("%lld
    ",l);
        return 0;
    }
    
  • 相关阅读:
    zoj 2406 Specialized FourDigit Numbers
    hdu 1016 Prime Ring Problem(深度优先搜索)
    【ObjectiveC】08self关键字
    【ObjectiveC】09空指针和野指针
    【零基础学习iOS开发】【01前言】01开篇
    【零基础学习iOS开发】【01前言】03前景和难易度分析
    多线程编程1NSThread
    【零基础学习iOS开发】【02C语言】02第一个C语言程序
    多线程编程2NSOperation
    【零基础学习iOS开发】【01前言】02准备
  • 原文地址:https://www.cnblogs.com/xzz_233/p/noiP2017-pjSol.html
Copyright © 2020-2023  润新知