Dertouzos
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1836 Accepted Submission(s): 577
Problem Description
A positive proper divisor is a positive divisor of a number n, excluding n itself. For example, 1, 2, and 3 are positive proper divisors of 6, but 6 itself is not.
Peter has two positive integers n and d. He would like to know the number of integers below n whose maximum positive proper divisor is d.
Input
There are multiple test cases. The first line of input contains an integer T (1≤T≤1^6), indicating the number of test cases. For each test case:
The first line contains two integers n and d (2≤n,d≤1^9).
Output
For each test case, output an integer denoting the answer.
Sample Input
9
10 2
10 3
10 4
10 5
10 6
10 7
10 8
10 9
100 13
Sample Output
1
2
1
0
0
0
0
0
4
【题意】 给出两个数n和d,要求求出小于n的以d为最大因子的数的个数(d本身除外)
【解题思路】 由题意可以转换为求m*d小于n中m的个数,其中m有如下要求:
1.m大于等于2,小于等于d;
2.m为素数;
3.m小于等于d的最小因子(除1以外);
于是可以想到线求出d的最小因子,求得素数表,取min(d的最小因子,(n-1)/d),再循环进行判断,得出答案;但由于2≤n,d≤1^9,以数组来存每个数的最小因子是存不下的,而且会超时,所以采用另一种方法,将10^5的素数找出来以数组存下(因为m小于min(d,(n-1)/d)),所以m是小于10^5的,在符合m的条件下对素数遍历,得出答案。
【AC代码】
#include<stdio.h>
#define maxn 100000
using namespace std;
int vis[maxn+5],prime[maxn+5],sum;
void findprime(int n)
{
int i,j;
sum=0;
for(i=2;i*i<n;i++) //若i*i>n,说明n之前的非素数都已经被标记了
{
if(vis[i])
continue;
for(j=i*i;j<n;j+=i)
vis[j]=1;
}
for(i=2;i<n;i++) //打素数表
if(!vis[i])
prime[sum++]=i;
}
int main()
{
int t,n,d;
scanf("%d",&t);
findprime(maxn);
while(t--)
{
int ans=0;
scanf("%d%d",&n,&d);
if(d>n)
{
printf("0\n");
continue;
}
for(int i=0;i<sum;i++)
{
if(prime[i]*d>=n)
break;
ans++;
if(d%prime[i]==0) //若该素数是d的第一个大于1的因子,则结束
break;
}
printf("%d\n",ans);
}
return 0;
}