POJ 2100 尺取法

题意

传送门 POJ 2100

题解

尺取法依次推进头部、尾部更新答案,由于序列连续,压缩为头尾即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#define min(a,b)    (((a) < (b)) ? (a) : (b))
#define max(a,b)    (((a) > (b)) ? (a) : (b))
#define abs(x)    ((x) < 0 ? -(x) : (x))
#define INF 0x3f3f3f3f
#define delta 0.85
#define eps 1e-5
#define PI 3.14159265358979323846
#define MAX_N 10005
using namespace std;
typedef long long LL;
struct result{
	LL n, s, t; // 记录答案区间连续元素个数以及头尾位置
	result(LL n, LL s, LL t):n(n), s(s), t(t){}
};
LL N;
vector<result> res;

bool cmp(result &a, result &b){
	return a.n > b.n;
}

int main(){
	while(~scanf("%lld", &N)){
		res.clear();
		LL s = 1, t = 1, sum = 0, limit = sqrt((double)N) + 1;
		for(;;){
			while(t < limit && sum < N){
				sum += t * t;
				// 推进尾部
				++t;
			}
			if(sum == N) res.push_back(result(t - s, s, t - 1));
			else if(sum < N) break;
			sum -= s * s;
			// 推进头部
			++s;
		}
		sort(res.begin(), res.end(), cmp);
		printf("%d\n", res.size());
		for(vector<result>::iterator ite = res.begin(); ite != res.end(); ite++){
			printf("%lld ", ite->n);
			for(LL i = ite->s; i <= ite->t; i++) printf("%lld%c", i, i == ite->t ? '\n' : ' ');
		}
	}
	return 0;
}
发布了91 篇原创文章 · 获赞 1 · 访问量 1598

猜你喜欢

转载自blog.csdn.net/neweryyy/article/details/105276722