【HDOJ】P2058 The sum problem

时间:2021-08-19 21:32:38

题意很简单就是给你一个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!= && m!=){
/*
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*=;
for (int i=sqrt(m);i>=;i--){
if (!(m%i)){
a=m/i;
b=i;
if ((a-b+)%) s=;
else s=(a-b+)/;
if ((a+b-)%) t=;
else t=(a+b-)/;
if (s<=n && t<=n && s>= && t>=) printf("[%d,%d]\n",s,t);
}
}
printf("\n");
}
return ;
}