原题转化为求a*b*c <=n中选出两个数组成有序对<a,b>的选法数。
令a<=b<=c....
分情况讨论:
(1)全部相等,即a = b = c.
选法有n^(1/3).
(2)有两个相等,则设相等的值为i,枚举i = 1到i*i <= n ,剩下的一个数的最大值为t = n/(i*i).当t >=i时,t = i这一种要删除,因为t = i则三个数都相等了,这种选法有3种,所以ans += 3*(t-1).t<i就ans += 3*t;
(3)三个数都不相等,则枚举a,b,其中b>a,剩下的数的最大值s = n/(a*b),如果s <= b,不满足····,假设s>b,则ans += 6*(s - b ).
分类讨论时要不重复,不遗漏······
贴代码:
1 #include<cstdio> 2 typedef long long int LL; 3 int main() 4 { 5 // freopen("in.txt","r",stdin); 6 LL n,ans; 7 int kase = 0; 8 while(~scanf("%I64d",&n)) 9 { 10 ans = 0; 11 for(LL i=1; i*i*i <=n; ++i) ++ans; 12 int A = ans; 13 for(LL i=1; i*i <=n ; ++i) 14 { 15 LL t = n/(i*i); 16 if(t >= i) ans += 3*(t-1); 17 else ans += 3*t; 18 } 19 for(LL a=1; a<=A; ++a) 20 { 21 LL k = n/a; 22 for(LL b=a+1; b*b <= k; ++b) 23 { 24 LL s = n/(a*b); 25 if(s > b) ans += 6*(s-b); 26 } 27 } 28 printf("Case %d: %I64d ",++kase,ans); 29 } 30 return 0; 31 }
注意n为long long int ·······