51nod 1138 连续整数的和(简单数学、等差数列)

来源:互联网 发布:陕西广电网络校园招聘 编辑:程序博客网 时间:2024/06/01 09:28

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示例

147

解题思路1

我真的不是来凑博客的[逃……]
当加和的个数i为奇数时,如1,2,3,4,5,设最中间的数字3为x,则可得i22x+x=n;当i为偶数时,如1,2,3,4,设最中间的两个数2+3=x,则可得k2x=n,枚举i可得x。则在奇数情况下,第一个数可表示为xi2;在偶数情况下,第一个数可表示为x2i2+1,特别地要剔除两个数加和等于n且这两个数相等的情况。

代码实现

#include<bits/stdc++.h>using namespace std;#define maxn 44722int 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=ia1+i(i1)21,则a1=2ni(i1)2i,因为最少需要两个数相加,所以2a1+i(i1)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;}
原创粉丝点击