尺取 POJ - 2100

版权声明:博客作者为blue bear,严禁他人在未经作者同意下进行商用转载 https://blog.csdn.net/weixin_44354699/article/details/87726821

尺取 POJ - 2100

题目链接:

[https://vjudge.net/contest/279018#problem/B ]
[http://poj.org/problem?id=2100]

题面

King George has recently decided that he would like to have a new design for the royal graveyard. The graveyard must consist of several sections, each of which must be a square of graves. All sections must have different number of graves. After a consultation with his astrologer, King George decided that the lengths of section sides must be a sequence of successive positive integer numbers. A section with side length s contains s 2 graves. George has estimated the total number of graves that will be located on the graveyard and now wants to know all possible graveyard designs satisfying the condition. You were asked to find them.
输入
Input file contains n — the number of graves to be located in the graveyard (1 <= n <= 10 14 ).
输出
On the first line of the output file print k — the number of possible graveyard designs. Next k lines must contain the descriptions of the graveyards. Each line must start with l — the number of sections in the corresponding graveyard, followed by l integers — the lengths of section sides (successive positive integer numbers). Output line’s in descending order of l.
输入样例
2030
输出样例
2
4 21 22 23 24
3 25 26 27

题意

翻译一下大概就是:给你一个数,让你找到一系列连续的整数;使得数的平方的和等于这个数。然后输出的时候先输出有多少个一系列的数,再输出每个有多少个数 再输出这些数 (有点绕口 看样例就懂了)
所谓尺取就是有两个指示器i,j一开始都指向第一个,然后j往后挪到达某个条件时i往后挪,(这一题的条件就是区间内的平方和是否等于该数,小了挪j,大了挪i,相等了记录)然后再j往后挪直到遍历到上限。复杂度是O(n²)。有点抽象,上代码吧。

代码

#include <stdio.h>
typedef long long ll;
struct NODE{//开的结构体记录区间
	int i,j;
}n[100000];
int main(){
	ll i,j,x,sum,flag;
	int num;
	scanf("%lld",&x);
	for(sum=num=0,i=j=1;i*i<=x;j++){
		sum+=j*j;
		if(sum==x){
			n[num].i=i;
			n[num++].j=j;
		}
		if(sum>x){
			while(i<=j){
				if(sum<x) {
					i--;
					sum+=i*i;
					break;
				}
				sum-=i*i;
				i++;
				//printf("%d %d %lld %lld\n",i,j,x,sum);//1 2 2 5
				if(sum==x){
					n[num].i=i;
					n[num++].j=j;
				}
			}
		}
	}
	if(num==0) puts("0");
	else {
		printf("%d\n",num);
		for(i=0;i<num;i++){
			printf("%d ",n[i].j-n[i].i+1);
			printf("%d",n[i].i);
			for(j=n[i].i+1;j<=n[i].j;j++) printf(" %d",j);
			puts("");
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44354699/article/details/87726821