1138 连续整数的和
给出一个正整数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
题解:
直接枚举超时,分析题中的数据,我们可以发现有这样的关系:2N = n(n-1+2a) (其中a为序列的首项,n为序列的项数),稍微化解就可以N = (n-1)n/2 + na;这样我们可以对1e9之内的所有可以等于n(n-1)/2 (n为整数)的数预处理出来然后这样枚举n(n-1)/2就可以了,就优化为了O(sqrt(n))的复杂度。具体实现见代码。
代码:
#include<iostream>
#include<cstring>
#include<math.h>
#include<stdlib.h>
#include<cstring>
#include<cstdio>
#include<utility>
#include<algorithm>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const int Max = 1e5+5;
const int mod = 1e9+7;
const int Hash = 10000;
const int INF = 1<<30;
const ll llINF = 1e18;
int n, cnt;
ll arr[Max];
ll f(int x)
{
return (x-1)*x/2;
}
void init( )
{
cnt = 2;
ll t = f(cnt);
while(t <= 1e9)
{
arr[cnt] = t;
cnt++;
t = f(cnt);
}
}
int main( )
{
//freopen("input.txt", "r", stdin);
init( );//N = (n-1)*n/2 + na;所以可以提前将n(n-1)/2枚举出来是O(sqrt(N))复杂度
while(cin>>n)
{
int i= 2;
stack<int> st;
while(arr[i] < n)
{
int a = (n-arr[i])/i;
if(a*i == n-arr[i])
st.push(a);
i++;
}
if(st.empty( ))
{
cout<<"No Solution"<<endl;
continue;
}
while(!st.empty( ))
{
printf("%d\n", st.top());
st.pop( );
}
}
return 0;
}