观察a+1,a+2…a+d
全部相加等于M
即(a+1+a+d)*d/2 = M,
这里d是平方,我们可以从长度d入手,这样就能把范围由M转换成M^1/2 ;
这里把代码中的①和②解释下:
①:当a+1,a+2…a+3相加等于M时,即
(a+1+a+d)*d/2 = M
而a最小是0,所以(d+1)*d/2=M时d去最大值,就是这步把时间复杂度减小的。
d就是sqrt(2*M)
②:(a+1+a+d)*d/2 = M
所以a*d + (d+1)*d/2 = M
所以要使等式成立,M-(d*d+d)/2必须是d的倍数。
#include<stdio.h>
#include<math.h>
int main()
{
int n,m,t;
int i,len;
while(scanf("%d%d",&n,&m),n!=0&&m!=0)
{
len=(int)(sqrt(m*2.0));
for(i=len;i>=1;i--)//注意i到1.i==1时是相同的数列
{
t=m-(i*i+i)/2;
if(t%i==0)
printf("[%d,%d]\n",t/i+1,t/i+i);
}
printf("\n");
}
return 0;
}
#include<stdio.h>
int main()
{
int n,m,i,s,len,M,a;
while(scanf("%d%d",&n,&m),n!=0&&m!=0)
{
s=0;
for(i=1;i<=n;i++)
{
s=s+i;
if(s>=m)
{
len=i;
break;
}
}
M=2*m;
for(i=len;i>0;i--)
{
if(M%i==0&&(M/i+1-i)%2==0)
{
a=(M/i+1-i)/2;
printf("[%d,%d]\n",a,a+i-1);
}
}
printf("\n");
}
return 0;
}
hdu 2058
最新推荐文章于 2020-04-24 16:49:52 发布