zoukankan      html  css  js  c++  java
  • CF1081E Solution

    题目链接

    题解

    \(\sum\limits_{i=1}^{2k}x_i\)\(sum\),因为前缀和均为完全平方数,可以设整数\(b^2=sum+x_{2k+1},a^2=sum+x_{2k+1}+x_{2k+2}\)。进一步推导得\(a^2-b^2=x_{2k+2}\),所以\(x_{2k+2}=(a+b)(a-b)\)。因此我们可以枚举\(x_{2k+2}\)的因数\(y,z(y\cdot z=x_{2k+2},y\ge z)\),如果\(y,z\)同奇同偶则一定可以解出\(a,b\)\(a=\frac{y+z}{2},b=\frac{y-z}{2}\),同奇偶时存在整数解)。而\(x_{2k+1}=b^2-sum\)。当存在多组符合条件的因数时,我们需取\(y,z\)最接近的一组。此时\(y+z,y-z\)最小,解出的\(a,b\)也最小,因为存在答案上界,利用贪心思想可知这样最优。

    具体实现:枚举\(k\)(其实就是枚举偶数项),分解\(x_{2k+2}\),记录答案,如果无\(a,b\)正整数解则判断无法构造,如果可以更新\(sum\)的值。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e5+10,inf=0x3f3f3f3f3f3f3f3f;
    int x[N],y[N];//x:偶数项,y:奇数项
    signed main()
    {
    	int n,sum=0;
    	scanf("%lld",&n);
    	for(int i=1;i<=n/2;i++) scanf("%lld",&x[i]);
    	memset(y,0x3f,sizeof(y)); 
    	for(int i=1;i<=n/2;i++)//枚举偶数项(k=i-1)
    	{
    		for(int j=1;j*j<=x[i];j++)//分解偶数项
    		{
    			if(x[i]%j) continue;  
    			if(j%2==x[i]/j%2)//如果同奇同偶
    			{
    				int b=(x[i]/j-j)/2,t=b*b-sum;//t:当前解出的奇数项
    				if(t>0) y[i]=min(y[i],t);
    			}
    		}
    		if(y[i]==inf) {printf("No"); return 0;}//如果无正整数解
    		sum+=x[i]+y[i];//更新sum
    	}
    	printf("Yes\n");
    	for(int i=1;i<=n/2;i++) printf("%lld %lld ",y[i],x[i]);
    	return 0;
    }
    
  • 相关阅读:
    重构drf后的环境变量配置
    分离的前后台交互
    虚拟环境的搭建
    Python
    Python
    Python
    Python操作MongoDb数据库
    Python操作SQLite/MySQL/LMDB
    数据库-如何创建SQL Server身份验证用户
    Python
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14369690.html
Copyright © 2011-2022 走看看