题意:
结界给出一个数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; }
文章来源: POJ 2100(尺取法+嵌套pair)