标签:数论
该题确实在个简单的问题,因为可能形式很简单,但它又不是那么的简单。
如果这个题选择有两个for循环来写的话,那毫无疑问将超时,所以需要仔细分析一下,可以看出,N=i*j+i+j可以变形为:N+1=( i+1)*( j+1),且由 0<i<=j,可知:1<( i+1)<=( j+1),所以就以(i+1)为基准来进行循环,所以只需要单层循环即可。
再有,由于要考虑它的重复性,所以循环只需要进行到sqrt(N+1)即可,往后再循环的必重复。本题 i 要从1开始,所以 i+1 就要从2开始循环,一直到sqrt(N+1)(其实可以等于sqrt( N+1),此时 i=j,符合题意)。
当我想到这一步,我就感觉很明了了,易知(j+1)=( N+1)/(i+1),所以在循环里我用的判断是:if(((N+1)/(i+1))*( i+1)==n+1)
真不知道当时怎么短路了,会去这样判断,还是超时,后来到网上一看,才知道改成:if((N+1)%(i+1)==0)就行了,就解决了超时的问题。
耗时2562ms。
代码如下:
#include <stdio.h> #include <string.h> #include <math.h> typedef __int64 int64; int main() { int64 i,j,n,count,t,k; scanf("%d",&t); while(t--) { count=0; scanf("%I64d",&n); k=sqrt(n+1); for(i=2;i<=k;i++)<span style="white-space:pre"> </span>//这里的i指的是i+1 if((n+1)%i==0) count++; printf("%d\n",count); } return 0; }
①:奇 * 奇 + 奇 + 奇 = 奇
②:偶 * 偶 + 偶 + 偶 = 偶
③:奇 * 偶 + 奇 + 偶 = 奇
故可得,若 N 为偶数,那 i 和 j 也都是偶数,那 i+1就是从3开始,每次增加2,所以只需判断一下N是不是偶数就行了:
if(n%2==0) { for(i=3;i<=k;i+=2) if((n+1)%i==0) count++; }
#include <stdio.h> #include <string.h> #include <math.h> typedef __int64 int64; int main() { int64 i,j,n,count,t,k; scanf("%d",&t); while(t--) { count=0; scanf("%I64d",&n); k=sqrt(n+1); if(n%2==0) { for(i=3;i<=k;i+=2) if((n+1)%i==0) count++; } else { for(i=2;i<=k;i++) if((n+1)%i==0) count++; } printf("%d\n",count); } return 0; }
HDU2601,An easy problem,布布扣,bubuko.com
标签:数论
原文地址:http://blog.csdn.net/u013068502/article/details/38357575