poj 2100 尺取法(尺度法)

Posted alking1001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 2100 尺取法(尺度法)相关的知识,希望对你有一定的参考价值。

poj 2100 尺取法(尺度法)

题意

给你一个数N,然后找到一个连续的序列,使得这个序列中的数的平方和等于N

输出需要注意的是第一行为解的个数,剩下的每行先输出序列的长度,然后输出序列。按照序列的长度进行降序输出。

解题思路

没啥好说的,使用尺度法,进行枚举各个区间上的数。

需要注意的是数字1的答案为:

1
1 1

代码实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const int MAXN=1E6+7;
ll n;
struct node{
    ll length, begin;
    //把答案放在这里,仔细一想其实不用排序,本来就是有序的。
    friend bool operator< (const node &a, const node &b)
    {
        if(a.length == b.length)
            return a.begin < b.begin;
        else return a.length > b.length;
    }
};
node nod[MAXN];
int main()
{
    cin>>n;
    ll lt=1, rt=2, sum=1;
    int cnt=0;
    while(1)
    {
        while(sum < n && rt <= ll( sqrt(n) + 1) )
        {
            sum+=rt*rt;
            rt++;
        }
        if(sum < n) break;
        if(sum==n)
        {
            nod[cnt].begin=lt;
            nod[cnt++].length=rt-lt;
        }
        sum-=lt*lt;
        lt++;
    }
//  sort(nod, nod+cnt);
    cout<<cnt<<endl;
    for(ll i=0; i<cnt; i++)
    {
        lt=nod[i].begin;
        cout<<nod[i].length; 
        for(ll j=lt; j<lt+nod[i].length; j++)
        {
            cout<<" "<<j;
        }
        cout<<endl;
    }
    return 0;
}

以上是关于poj 2100 尺取法(尺度法)的主要内容,如果未能解决你的问题,请参考以下文章

POJ2100 Graveyard Design(尺取法)

题解报告:poj 3061 Subsequence(二分前缀法or尺取法)

POJ3162 Walking Race(树形DP+尺取法+单调队列)

尺取法 poj 2566

poj3320(尺取法)

poj2739(尺取法+质数筛)