【题意】
国王G最近决定重新设计一下皇陵。这个陵园必须包括两个部分:每个坟墓必须是正方形的;必须由不同数量的坟墓组成。国王G在和他的占星家们讨论一番,他决定坟墓的边长必须是连续正整数的序列。一条边长为
s
包含
限制条件:
1≤n≤1014
【提炼】
求k组满足条件的
a0…ar−1
(每组
r
个数),其平方之和等于输入的正整数
【分析】
求连续平方数之和等于给定的数
n
,dp或者尺取法。
题目要求存下满足条件的多组序列。
由于要提前输出组数和每组的长度,所以采用vector + pair来存数组。右戳链接
Tips:判读退出条件注意暂存一个值来判断,不然wa到你怀疑人生。
【时间复杂度】
根据完全平方数的性质,正整数n以内的完全平方数数量总数为
O(n√)
【代码】
/*
coder: Tangent Chang
date: 2017/5/11
A day is a miniature of eternity. by Emerson
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 10005;
vector< pair<ll, ll> > ans;
int main() {
ll n;
while (scanf("%lld", &n) != EOF) {
ans.clear();
ll kk = 0;
ll s = 1, t = 1, sum = 0, sq = 0;
if (n == 0) break;
while (1) {
while (sum < n) {
sq = t * t;
sum += sq;
t++;
}
if (sq > n) break;
if (sum == n) {
ans.push_back(make_pair(s, t));
}
sum -= s * s;
s++;
}
kk = ans.size();
printf("%lld\n", kk);
for (ll i = 0; i < kk; ++i) {
ll l = ans[i].first;
ll r = ans[i].second;
printf("%lld", r - l);
for (ll j = l; j < r; ++j) {
printf(" %lld", j);
}
puts("");
}
}
return 0;
}