题意很简单就是给你一个N和M,让你求在1-N的那些个子序列的值等于M

首先暴力法不解释,简单超时

再仔细想一想可以想到因为1-N是一个等差数列,可以运用我们曾经学过的只是来解决

假设开始的位置为s,结束的位置为t,那么一定要满足这个等式

(s+t)(t-s+1)=2*m

又因为S和T都是整数,所以左边的括号中每一项都是等式

所以s+t和t-s+1一定是2*m的因式

所以分解因式并带入就可以求出s和t

假设

s+t=a

t-s+1=b

a*b=2*m

解得

s=(a-b+1)/2

t=(a+b-1)/2

很明显a>b,因为题目都是从小到大排列,所以在选取的时候可以倒叙进行寻找a

另外要注意并不是每一个a,b都可以算出一个s,t的,所以要临时判断一下

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int n,m,s,t,sum,a,b;

int main(){
    while(cin>>n>>m,n!=0 && m!=0){
        /*
        s=1;
        t=1;
        sum=0;
        for (t=1;t<=n;t++){
            sum+=t;
            while(sum>m) sum-=s++;
            if (sum==m) printf("[%d,%d]\n",s,t);
        }
        //暴力版
        */
        m*=2;
        for (int i=sqrt(m);i>=1;i--){
            if (!(m%i)){
                a=m/i;
                b=i;
                if ((a-b+1)%2) s=0;
                else s=(a-b+1)/2;
                if ((a+b-1)%2) t=0;
                else t=(a+b-1)/2;
                if (s<=n && t<=n && s>=1 && t>=1) printf("[%d,%d]\n",s,t);
            }
        }
        printf("\n");
    }
    return 0;
}
View Code