现在的位置: 首页 > 综合 > 正文

2005年百度之星程序设计大赛试题初赛题目-题1

2013年08月15日 ⁄ 综合 ⁄ 共 2304字 ⁄ 字号 评论关闭

第一题(共四题 100 分):连续正整数( 10 分) 

题目描述:一个正整数有可能可以被表示为 n(n>=2) 个连续正整数之和,如: 

15=1+2+3+4+5 
15=4+5+6 
15=7+8 

请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。 

输入数据:一个正整数,以命令行参数的形式提供给程序。 

输出数据:在标准输出上打印出符合题目描述的全部正整数序列,每行一个序列,每个序列都从该序列的最小正整数开始、以从小到大的顺序打印。如果结果有多个序列,按各序列的最小正整数的大小从小到大打印各序列。此外,序列不允许重复,序列内的整数用一个空格分隔。如果没有符合要求的序列,输出 “NONE” 。 

例如,对于 15 ,其输出结果是: 
1 2 3 4 5 
4 5 6 
7 8 
对于 16 ,其输出结果是: 
NONE 

评分标准:程序输出结果是否正确。

my answer:

思路:1 <= start < end <= n/2+1,start从1开始遍历,end用二分搜索

总结:(1)题目要求从命令行输入,没有仔细阅读题目(2)n用长整型比较好

优化:start不需要一个一个遍历

#include <iostream>
using namespace std;
int main()
{
	
	int n, start, end, i, sum;
	while(cin>>n)
	{
		bool flag = 0;
		start = 1;
		while(start <= n/2)
		{
			int low = start, high = n/2+1, mid;
			while(high >= low)
			{
				mid = (high + low)/2;
				sum = (start + mid) * (mid - start + 1);
				if(sum == n * 2)
				{
					flag = 1;
					for(i = start; i <= mid; i++)
					{
						if(i != start)cout<<' ';
						cout<<i;
					}
					cout<<endl;
					break;
				}
				else if(sum < n * 2)
					low = mid + 1;
				else if(sum > n * 2)
					high = mid - 1;
			}
			start++;
		}
		if(!flag)cout<<"NONE"<<endl;
	}
	
	return 0;
}

牛A陈世熹的比赛答题源码:

结果可以分为两类,以15为例:

一种是像12345和456这样的,每个序列的个数是奇数个,另这个序列的中间的数为mid,那么n%mid==0&&(n/mid)%2==1

另一种是像78这样的序列,每个序列的个数是偶数个,另这个序列中第一个数+倒数第一个数==第二个数+倒数第二个数==sum,那么sum%2==1&&n%sum==0

#include <iostream> 
#include <cstdio> 
#include <utility> 
#include <algorithm> 
#include <cmath> 

using namespace std; 

int N, M; 
pair<int, int> List[65536]; 

int main(int argc, char* args[]) 
{ 
	int I, J, Max, A, B; 
	if (argc <= 1) return 0; 
	sscanf(args[1], "%d", &N); 
	M = 0; 
	Max = (int)sqrt((double)N) * 2; 
 	for (I = 2; I <= Max; I++) 
		if (I & 1) 
		{ 
			if (N % I == 0) 
			{ 
				J = N / I; 
				A = J - I / 2; 
				B = J + I / 2; 
				if (A >= 1) List[M++] = make_pair(A, B); 
			} 
		} 
		else 
		{ 
			if (N % I != 0 && N % (I / 2) == 0) 
			{ 
				J = N / I; 
				A = J - I / 2 + 1; 
				B = J + I / 2; 
				if (A >= 1) List[M++] = make_pair(A, B); 
			} 
		} 
	if (M == 0) 
		printf("NONE\n"); 
	else 
	{ 
		sort(List, List + M); 
		for (I = 0; I < M; I++) 
		{ 
			printf("%d", List[I].first); 
			for (J = List[I].first + 1; J <= List[I].second; J++) 
				printf(" %d", J); 
			printf("\n"); 
		} 
	} 
	return 0; 
}

牛B楼天城的比赛答题源码,我表示完全没看懂

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <iostream>
using namespace std;

#define _MAXL 2000000 

void GetN(char *s,long long &N) 
{ 
	N=0; 
	for (int i=0;s[i];i++) 
		N=N*10+(s[i]-48); 
} 
void print_bigint(long long n) 
{ 
	if (n>=10) 
		print_bigint(n/10); 
	printf("%d",int(n%10)); 
} 
void Solve(long long N) 
{ 
	bool find_answer=false; 
	long long L,T,A1,k; 
	for (L=2;L<=_MAXL && L*(L-1)/2<N;L++); 
	for (L--;L>=2;L--) 
	{ 
		T=L*(L-1)/2; 
		if (N>T && (N-T)%L==0) 
		{ 
			find_answer=true; 
			A1=(N-T)/L; 
			for (k=0;k<L;k++) 
			{ 
				if (k>0) 
				printf(" "); 
				print_bigint(A1+k); 
			} 
			printf("\n"); 
		} 
	} 
	if (!find_answer) 
	printf("NONE\n"); 
} 
int main(int argc,char *arg[]) 
{ 
	long long N; 
	GetN(arg[1],N); 
	Solve(N); 
	return 0; 
}

抱歉!评论已关闭.