描述
One day Teddy met a old man in his dream , in that dream the man whose name was“RuLai” gave Teddy a problem :
Given an N , can you calculate how many ways to write N as i * j + i + j (0 < i <= j) ?
Teddy found the answer when N was less than 10…but if N get bigger , he found it was too difficult for him to solve.
Well , you clever ACMers ,could you help little Teddy to solve this problem and let him have a good dream ?
-
输入
- The first line contain a T(T <= 2000) . followed by T lines ,each line contain an integer N (0<=N <= 10^11). 输出
- For each case, output the number of ways in one line 样例输入
-
2 1 3
样例输出
-
0 1
很显然,找出满足n=i * j + i + j (0 < i <= j) 的个数。。
但很多人(也包括我T T)第一想法都是用两个for循环,但无论怎样改都是超时ヽ(≧□≦)ノ。因为N (0<=N <= 10^11),,这说明什么呢,反正我以后要好好看题了。
超时代码:
#include<stdio.h>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int sum=0;
for(int j=1; j<=n; j++)
{
for(int i=1; i<=j; i++)
{
if(n==(i*j+i+j))
sum++;
}
}
printf("%d\n",sum);
}
return 0;
}
其实这道题用了一个技巧,我看别人都是这样写的,才发现数学很重要T T.
n=i*j+i+j转化为n+1=i*j+i+j+1即(n+1)=(i+1)*(j+1),
代码如下:
#include<stdio.h>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int sum=0;
for(int i=2; i*i<=(n+1); i++)
{
if((n+1)%i==0)sum++;
}
printf("%d\n",sum);
}
return 0;
}
本人菜鸟一个,,多多见谅。