连续整数固定和(C百例 & 51nod 1138)

来源:互联网 发布:如何更改淘宝店铺行业 编辑:程序博客网 时间:2024/05/18 07:35

书上讲了一种提高效率的方法。原始算法:用i遍历1到n-1,如果i到j的和等于n那么就输出相应的结果。我们可以发现当sum(i,j)=n时,继续j++,sum+=j,计算的sum肯定是大于n的,于是便在sum(i,j)=n输出结果后,sum-=i,再继续sum+=j等后续工作,这样避免了无用功。

#include <iostream>#include<cstdio>using namespace std;void f(int x){    int i=1,j=2,sum=i;    while(i<=x/2){    if(sum>=x)break;    else if(sum<x){    for(;j<=x/2+1;j++){    sum+=j;    if(sum==x){    printf("%d~%d\n",i,j);    sum-=i;    i++;    if(i>x/2)break;    }    else if(sum>x){    do{    sum-=i;    i++;    if(sum==x){    printf("%d~%d\n",i,j);    break;    }    else if(sum<x)break;    }while(i<=x/2&&sum>x);    }    }    }    }}int main(){    int n;    while(cin>>n){        f(n);    }    return 0;}

在51nod也发现了相关的问题:

http://www.51nod.com/onlineJudge/solutionRank.html#!problemId=1138

给出一个正整数N,将N写为若干个连续数字和的形式(长度 >= 2)。例如N = 15,可以写为1 + 2 + 3 + 4 + 5,也可以写为4 + 5 + 6,或7 + 8。如果不能写为若干个连续整数的和,则输出No Solution。

Input
输入1个数N(3 <= N <= 10^9)。
Output
输出连续整数中的第1个数,如果有多个按照递增序排列,如果不能分解为若干个连续整数的和,则输出No Solution。

分析:设m是连续的数字个数,那么第一位数字一定满足:,这是一个减函数,所以可以确定对应的查找范围。同时,当m时偶数时,n%m=m/2;当m是奇数时,

#include <iostream>#include <cstdio>using namespace std;int midfind(int n){    int l=2,r=n/2,mid,ans=0;    while(l<=r){        mid=(l+r)>>1;        if(n/mid-mid/2>0){            ans=mid;            l=mid+1;        }        else r=mid-1;    }    return ans;}int main(){    //freopen("cin.txt","r",stdin);    int n;    while(cin>>n){        int len=midfind(n);        bool flag=0;        for(int i=len;i>=2;i--){            if((i&1)&&n%i==0){                printf("%d\n",n/i-i/2);                flag=1;            }            else if(((i&1)==0)&&n%i==i/2){                    printf("%d\n",n/i-i/2+1);                    flag=1;            }        }        if(!flag) puts("No Solution");    }    return 0;}

另外,我&的优先级很低啊,甚至小于"==",所以书写的时候注意加括号。

0 0
原创粉丝点击