zoukankan      html  css  js  c++  java
  • Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020

    A. Kids Seating

    从4*n-2开始,每次输出减2。

    发现满足条件,不互质也不能相互整除

    B. Saving the City

    引爆花费a,安装花费b

    可知要引爆必定花费一个a,ans+=a

    对于两段1区间中间隔着的0,既可以用安装一个个1花费 cnt*b 也可以花费a引爆

    那么每次记录下来,然后比较 ans+=min(cnt*b,a)就行

    代码不贴了,开始想复杂了,导致过的很慢,码风也很丑陋

    C. The Delivery Dilemma

    给定两个序列,表示 取走某一个物品的a值和b值。

    我们要取每一个物品,通过a值取的贡献取大,通过b值取的贡献累加,最后两者再取大。

    思路就很明显了,按a排序,每次取i,那么i之前的物品都可以通过a值取,也就是没有花费。

    i之后的物品,累加b值,然后两者取大,就是该做法的最后答案。

    ll ans,sum[200007];
    struct nod{
        ll a,b;
    }node[200007];
    int cmp(nod x,nod y){
        return x.a<y.a;
    } 
    int t,n;
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            ans=inf;
            for(int i=1;i<=n;++i)    scanf("%lld",&node[i].a);
            for(int i=1;i<=n;++i)    scanf("%lld",&node[i].b);
            sort(node+1,node+1+n,cmp);
            for(int i=1;i<=n;++i)    sum[i]=sum[i-1]+node[i].b;
            for(int i=1;i<=n;++i){
                if(node[i].a>sum[n]-sum[i])
                    ans=min(ans,node[i].a);
                else 
                    ans=min(ans,sum[n]-sum[i]);
            }
            ans=min(ans,node[n].a);
            ans=min(ans,sum[n]);
            printf("%lld
    ",ans);
        }
        return 0;
    }

    思路二:二分

    不对a进行排序,直接对答案进行二分,判断当前的答案是否能满足条件。

    如果物品i的a值大于我的答案x,那么sum累加b值。

    如果最后b值反而大于x,那么不成立。

    成立的话说明,x还能继续缩小,让更多的物品去贡献b值到sum。

    以下是队友优秀的码风

    ll a[N],b[N],n;
    int check(ll x){
        ll ans=0;
        FR(i,1,n)
            if(a[i]>x)ans+=b[i];
        if(ans>x)return 0;
        return 1;
    }
    int main(){
        int t;
        string s;
        scanf("%d",&t);
        while(t--){
            scanf("%lld",&n);
            ll sum=0,maxn=0;
            FR(i,1,n){
                scanf("%lld",&a[i]);
                maxn=max(maxn,a[i]);
            }
            FR(i,1,n){
                scanf("%lld",&b[i]);
                sum+=b[i];
            }
            ll l=1,r=max(maxn,sum);
            ll mid;
            while(l!=r){
                mid=(l+r)/2;
                if(check(mid))r=mid;
                else l=mid+1;
            }
            printf("%lld
    ",l);
        }
        return 0;
    }

    D. Extreme Subtraction

    两种操作法,一种是从头到i都减1,第二种事从尾到i都减1

    那么先差分,我们的目标就是差分数组都为0

    操作1使得【1,i+1】    操作2使得【i,n+1】

          -1     +1          -1 +1

    很明显了,差分数组中间的任意值都能被操作12改为0,我们并不在意n+1位的差分是多少

    那么a1就成了限制我们操作的条件,对于差分数组中的负值,我们只能通过操作1操作。

    如果一个题看起来像差分,写起来也像,那他就是差分

      a[0]=0;
      for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        c[i]=a[i]-a[i-1];
      }
      int res=0;
      for(int i=2;i<=n;i++)
        if(c[i]<0) res=res+(-1)*c[i];
      if(res<=a[1]) printf("YES
    ");
      else printf("NO
    ");
  • 相关阅读:
    shell编程——循环执行
    ubuntu 设置管理 集锦
    27. 计算FPS
    29 GameProject4(+GUI)
    26. D3D显示文本
    30. D3D特效
    28. GUI
    32. 细节映射
    25. GameProject3
    Direct3D渲染到纹理 (部分转)
  • 原文地址:https://www.cnblogs.com/PdrEam/p/13923254.html
Copyright © 2011-2022 走看看