zoukankan      html  css  js  c++  java
  • Codeforces Round #517 (Div. 2) C. Cram Time(思维+贪心)

    https://codeforces.com/contest/1065

    题意

    给你a,b,让你找尽量多的自然数,使得他们的和<=a,<=b,用在a和b的自然数不能重复

    思路

    • 假如只有一个数a让你去找,问题就很简单了,就是找到一个x,使得x尽量大,且x*(x+1)/2<=a,意味着答案就是1~x
    • 我的思路是从1开始累加,加到一个不能再加的数时,向后退一个数,加上n-sum(1~a[i-1])(ps:a[i+1]为不能再加的数)

    错误贪心思想:假如加到不能再加,同样是只能再加一个数了,不如把小的数留给后面

    • 然后就一直wa

    • 正确思路

    • 贪心策略有问题,因为留给第一个数的不一定是[1,2...5,6,100]这样两段数,有可能根据a,b的大小,第一个数也有可能是三段,四段。。。

    • 设c=a+b,那么统一起来考虑,那么组成a和b的数一定为[1~x],其中(1+x)*x/2<=c,且x最大,

    • 那么让x1<=a,且x1尽量大,因此找出x后,从大到小扫,确保能把a尽可能填满,那么剩下数的和一定<=b

    #include<bits/stdc++.h>
    #define ll long long
    #define pb push_back
    using namespace std;
    ll a,b,sum,i;
    vector<ll>A,B;
    int main(){
        cin>>a>>b;
        sum=a+b;
        for(i=1;;i++){
            if(i*(i+1)/2>sum)break;
        }i--;
        for(;i>0;i--){
            if(a>=i){
                A.pb(i);a-=i;
            }else B.pb(i);
        }
        cout<<A.size()<<endl;
        for(i=0;i<A.size();i++)printf("%lld ",A[i]);cout<<endl;
        cout<<B.size()<<endl;
        for(i=0;i<B.size();i++)printf("%lld ",B[i]);cout<<endl;
    }
    
  • 相关阅读:
    34. Find First and Last Position of Element in Sorted Array
    42. Trapping Rain Water
    HDU-2952 Counting Sheep (DFS)
    HDU-1518 Square(DFS)
    HDU-1253 胜利大逃亡 (BFS)
    HDU-1026 Ignatius and the Princess I (BFS)
    最小生成树之Prim算法,Kruskal算法
    HDU-1495 非常可乐(BFS)
    strncpy 用法
    字符串函数总结
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/9928651.html
Copyright © 2011-2022 走看看