• Codeforces Round #592 (Div. 2)


    B. Rooms and Staircases

    从前往后,或者从后往前枚举下该位置一二层各走一次

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define sc(x) scanf("%I64d",&x);
    #define pb push_back
    #define fi first
    #define se second
    #define P pair<int,int>
    #define si signed
    char s[1005];
    int n;
    si main()
    {
        int t;
        sc(t);
        while(t--){
            sc(n);
            scanf("%s",s+1);
            int ans=0;
            int p=0,t=0;
            for(int i=1;i<=n;i++){
                if(s[i]=='1'){
                    t+=1;
                }
            }
            if(t==n){
                cout<<2*t<<'
    ';
            }else{
                ans=2*t+n-t;
                if(t==0){cout<<n<<'
    ';continue;}
                int ed= 0;
                for(int i=n;i>=1;i--){
                    if(s[i]=='1'){
                        ed= i;
                        break;
                    }
                }
                p=0;
                for(int i=1;i<=ed;i++){
                    if(s[i]=='1'){
     
                        ans=max(ans,p+2*(ed-i+1));
                        p+=2;
                    }
                    else {ans=max(ans,p+2*(ed-i+1));p++;}
                }
                ed =1;
                for(int i=1;i<=n;i++){
                    if(s[i]=='1'){
                        ed= i;
                        break;
                    }
                }
                p=0;
                for(int i=n;i>=ed;i--){
                    if(s[i]=='1'){
     
                        ans=max(ans,p+2*(i-ed+1));
                        p+=2;
                    }
                    else {ans=max(ans,p+2*(i-ed+1));p++;}
                }
                cout<<ans<<'
    ';
            }
        }
    }

    C. The Football Season

    给定 n,p,w,d;w<d

    要求

    x⋅w+y⋅d=p

    x+y+z =n

    x⋅w+y⋅d=p

    x+y< =n

    被扩展欧几里得坑了==

    数据范围爆long long

    先求下__gcd(w,d) ,如果p%__gcd(w,d)!=0,直接判无解

    容易发现x越大,x+y就会越大

    然后x从p/w+1往0开始枚举,不超过d的范围一定能找到合适的解

    如果没找到,说明不能满足x+y<=n,输出-1

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    signed main()
    {
       int  n,p,d,w;
       scanf("%I64d%I64d%I64d%I64d",&n,&p,&w,&d);
       int a =__gcd(w,d);
       if(p%a!=0||p/w>n){
        cout<<"-1"<<endl;return 0;
       }
       for(int i = p/w+1,j=0;i>=0&&j<10*d;j ++,i--){
        if((p-i*w)%d==0){
            int x= (p-i*w)/d;
            if(x+i<=n&&x>=0){
                cout<<i<<' '<<x<<' '<<n-i-x<<endl;
                return 0;
            }
        }
       }
       cout<<-1<<'
    ';
     
    }

    D. Paint the Tree

    一棵树要求任意一条三长路上的三个点颜色不同

    所以只能是一条链

    记录下祖父,父节点颜色,dfs跑几遍就行

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define sc(x) scanf("%I64d",&x);
    #define pb push_back
    #define fi first
    #define se second
    #define P pair<int,int>
    #define si signed
    vector<int>G[100005];
    int C[100005][3];
    int A[100005];
    int B[100005];
    int n;
    void dfs(int x,int fa,int pa)
    {
     
        for(int i=0; i<3; i++)
        {
            if(i!=A[fa]&&i!=A[pa])
            {
                A[x]=i;
                break;
            }
     
        }
        for(int i=0; i<G[x].size(); i++)
        {
            if(G[x][i]!=fa)
            {
                dfs(G[x][i],x,fa);
            }
        }
     
     
    }
    si main()
    {
        sc(n);
        for(int i=0; i<3; i++)
        {
            for(int j=1; j<=n; j++)
            {
                sc(C[j][i])
            }
        }
        int a,b;
        for(int i=1; i<n; i++)
        {
            sc(a) sc(b);
            G[a].pb(b);
            G[b].pb(a);
            if(G[a].size()>2||G[b].size()>2)
            {
                puts("-1");
                return 0;
            }
        }
        A[0]=-1;
        /*cout<<dfs(1,0,0)<<endl;
        for(int i=1;i<=n;i++){
            cout<<B[i]+1<<' ';
        }*/
        for(int i=1; i<=n; i++)
        {
            if(G[i].size()==1)
            {
     
                int a=i,b=G[a][0],c=((G[b][0]==a)?G[b][1]:G[b][0]);
                int ans=1e18;
                for(int i=0; i<3; i++)
                {
                    for(int j=0; j<3; j++)
                    {
                        int t=0;
                        if(i!=j)
                        {
                            A[a]=i;
                            A[b]=j;
                            dfs(c,b,a);
                            for(int i=1; i<=n; i++)
                            {
                                t+=C[i][A[i]];
                            }
                            if(ans>t)
                            {
                                ans=t;
                                for(int i=1; i<=n; i++)B[i]=A[i];
                            }
                        }
     
                    }
                }
                cout<<ans<<'
    ';
                for(int i=1; i<=n; i++)
                {
                    cout<<B[i]+1<<' ';
                }
                return 0;
     
            }
        }
    }

    E. Minimizing Difference

    这题似曾相识

    给一个数组,k次操作,每次操作可以选择一个数加一或者减一

    求不超过k次操作后,该数组最大值最小值之差最小为多少

    思路:

    sort 维护一下前缀和

    二分答案

    check:

    从左至右

    滑动窗口,对每一个数字Ai,枚举它是下界,Ai+x是上界时的代价,取min

    然后从右至左

    判断一下最小代价是否大于k

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define sc(x) scanf("%I64d",&x);
    #define si signed
    int n,k;
    int A[100005];
    int B[100005];
    bool check(int x)
    {
        int t=1e18;
        int y=n,z=1;
        int i=n,cnt=0;
       // cout<<x<<"xxxxxxxxxxx"<<endl;
        while(y>=1)
        {
            if(i==0)i=1;
            for(i; i>=1; i--)
            {
                if(A[y]-A[i]>x)
                {
     
                    t =min(t,(A[y]-x)*i-B[i]+cnt);
                    //cout<<t<<" "<<i<<endl;
                    break;
                }
            }
             cnt=(B[n]-B[y-1]-A[y-1]*(n-y+1));
             y--;
        }
     
        cnt=0;
        i=1;
     
        while(z<=n)
        {
            if(i>n)i=n;
            for(i; i<=n; i++)
            {
                if(A[i]-A[z]>x)
                {
                    t =min(t,B[n]-B[i-1]-(A[z]+x)*(n-i+1)+cnt);
     
                    break;
                }
            }
             cnt=A[z+1]*z-(B[z]);
            z++;
        }
        //cout<<t<<endl;
     
        return t<=k;
    }
    si main()
    {
        sc(n);
        sc(k);
        for(int i=1; i<=n; i++)
        {
            sc(A[i])
        }
        sort(A+1,A+1+n);
        int l = 0,r=A[n]-A[1];
        for(int i=1; i<=n; i++){B[i]=A[i]+B[i-1];}
        while(l+1<=r)
        {
            int mid =(l+r)/2;
            if(check(mid))
            {
                r=mid;
            }
            else
            {
                l=mid+1;
            }
        }
        cout<<l<<endl;
        /*int ans = A[n]-A[1];
        for(int i=0; i<=n; i++)
        {
            if(k<((A[i]*i)-B[i]))
            {
                break;
            }//min
            k-=(A[i]*i)-B[i];
            int l=i,r=n;
            while(l+1<=r)
            {
                int mid=(l+r)/2;
                if(B[n]-B[mid]-(n-mid)*A[mid]<=k)
                {
                    r = mid;
                }
                else
                {
                    l = mid+1;
                }
            }
            int x= A[l-1],y=A[l];
              if(l-1<i){
                x=A[l];
            }
            while(x+1<=y)
            {
                int mid =(x+y)/2;
                if(B[n]-B[l-1]-(n-l+1)*mid<=k)
                {
                    y=mid;
                }
                else
                {
                    x=mid+1;
                }
            }
            int cnt=A[i];
            if(k-B[n]+B[l-1]+(n-l+1)*x>l-1&&l-1>0){
                cnt+=min(k/(l-1),x-A[i]);
            }
            ans=min(x-cnt,ans);
        }
        cout<<ans<<'
    ';*/
    }
  • 相关阅读:
    linux usb 驱动详解
    md5sum.c, md5.c, md5.h
    安装 Kali Linux 后需要做的 20 件事
    Readprocessmemory使用方法
    在Centos下安装matlab
    PE文件简单介绍
    MATLAB中导入数据:importdata函数
    数据交换工具Kettle
    编写你自己的单点登录(SSO)服务
    AVL树
  • 原文地址:https://www.cnblogs.com/liulex/p/11781092.html
Copyright © 2020-2023  润新知