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

来源:互联网 发布:图的连通性判断算法 编辑:程序博客网 时间:2024/05/16 12:22

第一题(共四题 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; }


原创粉丝点击