题意:
结界给出一个数n。你要求一段连续的数,这些数的平方和等于n。
Input
输入一个整数n,1<=n<=10^14;
Output
输出一个数k,k为解的个数。接下来的k行为解,每一行的解要先输出这个解中包含的数字个数,然后从小到大输出解中包含的数字。解的输出顺序要按照所包含的数字个数降序排列。
Sample Input
2030
Sample Output
2 4 21 22 23 24 3 25 26 27
思路:
首先,不能打表,会MLE。看了别人的用pair<ll,pair<ll,ll> >这个高大上的东西来存储答案,学习了!因为尺取法是让r从开头加到sum>n,所以答案的顺序已经是降序了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const ll maxn=1e14+5;
const double eps=1e-8;
const double PI = acos(-1.0);
#define p pair<ll,pair<ll,ll> >
p ans[1010];
int main()
{
ll n;
while(~scanf("%lld",&n))
{
ll l=1,r=1,sum=0,k=0;
while(1)
{
while(r*r<=n&&sum<n)
{
sum+=r*r;
r++;
}
if(sum<n)
break;
if(sum==n)
{
ans[k++]=p(r-l,pair<ll,ll>(l,r-1));
}
sum-=l*l;
l++;
}
printf("%d\n",k);
for(int i=0;i<k;i++)
{
printf("%lld",ans[i].first);
for(int j=ans[i].second.first;j<=ans[i].second.second;j++)
{
printf(" %lld",j);
}
puts("");
}
}
return 0;
}