Description
给出一个正整数N,将N写为若干个连续数字和的形式(长度 >= 2)。例如N = 15,可以写为1 + 2 + 3 + 4 + 5,也可以写为4 + 5 + 6,或7 + 8。如果不能写为若干个连续整数的和,则输出No Solution。
Input
输入1个数N(3 <= N <= 10^9)。
Output
输出连续整数中的第1个数,如果有多个按照递增序排列,如果不能分解为若干个连续整数的和,则输出No Solution。
Input示例
15
Output示例
1
4
7
解题思路1
我真的不是来凑博客的[逃……]
当加和的个数i为奇数时,如1,2,3,4,5,设最中间的数字3为x,则可得
i2∗2x+x=n
;当i为偶数时,如1,2,3,4,设最中间的两个数2+3=x,则可得
k2∗x=n
,枚举i可得x。则在奇数情况下,第一个数可表示为
x−i2
;在偶数情况下,第一个数可表示为
x2−i2+1
,特别地要剔除两个数加和等于n且这两个数相等的情况。
代码实现
#include<bits/stdc++.h>
using namespace std;
#define maxn 44722
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
bool flag=false;
for(int i=maxn; i>=2; i--)
{
if(i%2)
{
int t=i/2*2+1;
if(n%t==0)
{
int x=n/t;
if(x-i/2>0)
{
cout<<x-i/2<<endl;
flag=true;
}
}
}
if(!(i%2))
{
int t=i/2;
if(n%t==0)
{
int x=n/t;
if(x/2-i/2+1>0&&x/2*2!=x)
{
cout<<x/2-i/2+1<<endl;
flag=true;
}
}
}
}
if(!flag)
cout<<"No Solution"<<endl;
return 0;
}
解题思路2
直接使用等差数列公式可得 n=i∗a1+i∗(i−1)2∗1 ,则 a1=2∗n−i∗(i−1)2∗i ,因为最少需要两个数相加,所以 2∗a1+i∗(i−1)2<=n ,则i的上界可近似表示为i<=sqrt(2*n),所以其中i的取值范围是[2,sqrt(2*n)]。
代码实现
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
int t=sqrt(n*2);
bool flag=false;
for(int i=t;i>=2;i--)
{
int x=2*n+i-i*i;
if(x%(2*i)==0&&x>0)
{
cout<<x/(2*i)<<endl;
flag=true;
}
}
if(!flag)
cout<<"No Solution"<<endl;
return 0;
}