1 条题解

  • 0
    @ 2025-8-24 22:29:47

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar luckydrawbox
    **

    搬运于2025-08-24 22:29:47,当前版本为作者最后更新于2021-03-19 20:32:00,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    传送门

    分析

    易得 ljcc 和学妹的总得分必定为 1+2+3++n1+2+3+……+n,由小学学过的等差数列求和可得总得分为 n(n+1)2=a+b\tfrac{n(n+1)}{2}=a+b,如何求 nn 呢?

    n2<n(n+1)<(n+1)2∵n^2<n(n+1)<(n+1)^2 n2<2(a+b)<(n+1)2∴n^2<2(a+b)<(n+1)^2 n<2(a+b)<n+1∴n<\sqrt{2(a+b)}<n+1  n=2(a+b)∴\ n=\left\lfloor\sqrt{2(a+b)}\right\rfloor

    n=sqrt(2*(a+b))

    我们求出 nn 后,判断 n(n+1)n(n+1) 是否与 2(a+b)2(a+b) 相等。

    • 若不相等,说明无解,直接输出 No,结束程序。

    • 若相等,说明有解,输出 nn,接下来开始构造

    构造的想法与P7071 [CSP-J2020] 优秀的拆分贪心相似,枚举 iinn11,若 aia≥i,则令 a-=i,并输出 ii,即尽量减去较大的得分,可以用决策包容性证明这个贪心是正确的。

    当然,你会注意到 a,ba,b 的最大值为 23112^{31}−1,加起来一定会超过 int 范围,所以要开 long long

    代码

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll a,b,n;//long long莫忘 
    int main()
    {
        cin>>a>>b;
        n=sqrt(2*(a+b));//求n 
        if(n*(n+1)!=2*(a+b))//判断是否相等 
        {
        	//无解 
        	cout<<"No";
        	return 0;
    	}
    	//有解 
    	cout<<n;
        for(int i=n;a;i--)//从n开始向下枚举 
        {
        	if(a>=i)
        	{
        		a-=i;//尽量减大的 
        		cout<<" "<<i;//注意格式 
    		}
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    6549
    时间
    1000ms
    内存
    500MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者