题目描述
对一个给定的自然数MM,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为MM。
例子:1998+1999+2000+2001+2002 = 100001998+1999+2000+2001+2002=10000,所以从1998到2002的一个自然数段为M=10000的一个解。
输入格式
包含一个整数的单独一行给出M的值(10<M<2,000,000)。
输出格式
每行两个自然数,给出一个满足条件的连续自然数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。
题解: 首先是自己本人的极弱AC代码 相当于就是一个 模拟
1.找出n的约数 用 n 去 ÷
2.
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 5 using namespace std; 6 const int range=2000010; 7 8 int n,a[range],ans=0,pos=0; 9 10 struct node{ 11 int start; 12 int end; 13 }an[2000010]; 14 15 bool cmp(node n1,node n2){ 16 return n1.start<n2.start; 17 } 18 19 int main(){ 20 cin>>n; 21 for(int i=2;i<n;i++){ //范围注意 22 if(n%i==0){ 23 a[ans++]=i; 24 } 25 } 26 for(int i=0;i<ans;i++){ 27 if(a[i]%2==0){ 28 int mi=(n-a[i])/(a[i]*2); 29 int q=((n-a[i])%(a[i]*2)); //本来想法是 mi%2 判断是否==0 但是由于 int 已经转型了 所以重新定义了一个 30 if(a[i]-mi>=0&&a[i]+mi<=n&&q==0){ 31 an[pos].start=a[i]-mi; 32 an[pos].end=a[i]+mi; 33 pos++; 34 } 35 } 36 else{ 37 if(n/a[i]%2==0){ 38 int q=(floor)(a[i]/2); 39 if(q-n/a[i]-1>=0&&q+n/a[i]<=n){ 40 an[pos].start=q-n/a[i]+1; 41 an[pos].end=q+n/a[i]; 42 pos++; 43 } 44 } 45 else{ 46 int mi=(n/a[i]-1)/2; 47 if(a[i]-mi<0){ // 给的测试点钟出现负数 相当于 一个abs() 48 an[pos].start=mi-a[i]+1; 49 } 50 else an[pos].start=a[i]-mi; 51 an[pos].end=a[i]+mi; 52 pos++; 53 } 54 } 55 } 56 sort(an,an+pos,cmp); 57 for(int i=0;i<pos;i++){ 58 cout<<an[i].start<<" "<<an[i].end<<endl; 59 } 60 if(n/2+n/2+1==n) cout<<n/2<<" "<<n/2+1; //判断 是否可以相邻两数相+ 61 return 0; 62 }
接下来是大佬代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int m; 4 int main(){ 5 cin>>m; 6 for(int k1=sqrt(2*m);k1>1;k1--)//枚举k1(注意是k1>1而不是k1>=1) 7 if(2*m%k1==0 && (k1+2*m/k1)%2){//如果K2是整数而且与K1一奇一偶 8 int k2=2*m/k1; 9 cout<<(k2-k1+1)/2<<" "<<(k1+k2-1)/2<<endl;//输出答案 10 } 11 return 0; 12 }
此处附大佬 blog
https://www.luogu.org/blog/remenber/solution-p1147
侵删