POJ 2100 · Graveyard Design【尺取法】

【题意】
国王G最近决定重新设计一下皇陵。这个陵园必须包括两个部分:每个坟墓必须是正方形的;必须由不同数量的坟墓组成。国王G在和他的占星家们讨论一番,他决定坟墓的边长必须是连续正整数的序列。一条边长为 s 包含s2个坟墓。国王G想要估计现在陵园中所有尽可能满足设计条件的坟墓总数。你能帮他找到吧。
限制条件:
1n1014

【提炼】
求k组满足条件的 a0ar1 (每组 r 个数),其平方之和等于输入的正整数n

【分析】
求连续平方数之和等于给定的数 n ,dp或者尺取法。

题目要求存下满足条件的多组序列。

由于要提前输出组数和每组的长度,所以采用vector + pair来存数组。右戳链接

Tips:判读退出条件注意暂存一个值来判断,不然wa到你怀疑人生。

【时间复杂度】
根据完全平方数的性质,正整数n以内的完全平方数数量总数为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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值