题意很简单就是给你一个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; }