题解:CF1031C Cram Time

· · 题解

思路

我们假设一个 c 数组,长度为 n。且 n\sum_{i = 1}^{n}i \le a + b 的最大值。则:\

则 $a$ 一定能由数组中若干个不同的数相加而成。\ $b$ 则由剩下的若干个不同的数相加而成。\ $n$ 最大为 $\sum_{i=1}^{n}i+n\ge a+b$ 的最小值,即 $\frac{n(n+1)}{2}+n\ge a+b$ 的最小值,$n<10^5$。 ## 要注意的点 - $a$ 时间最好要倒着减,(从大减到小)而且还要判断现在的时间够不够 $c_x$。~不然时间会用不完,不是最好结果~ - $a$ 用过的要标记一下,第二轮没标记过的直接输出($c$ 数组和为 $a+b$)。 ## code: ```cpp #include <bits/stdc++.h> using namespace std; int a,b,ans,num,s,c[100001];//c数组最大为[n(n+1)]/2<1^5 bool v[100001];//标记第一轮 vector<int>a1; int main(){ cin>>a>>b; s=a+b; for(int i=1;i<=s;i++){ if(2*i+1>s){ c[++num]=s; break; } c[++num]=i; s-=i; } for(int i=num;i>=1;i--){//一定要倒过来才能保证刚好用完a时间 if(c[i]<=a){ a-=c[i]; a1.push_back(c[i]); v[i]=1; } if(!a)break; } cout<<a1.size()<<endl; for(int i=0;i<a1.size();i++){ cout<<a1[i]<<" "; } cout<<endl<<num-a1.size()<<endl;//剩下的 for(int i=1;i<=num;i++){ if(!v[i]){ cout<<c[i]<<" "; } } return 0; } ```