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;
}

posted @ 2020-02-04 13:04  ALKING1001  阅读(119)  评论(0编辑  收藏  举报