GCD
题目描述
a和b的最大公约数(Greatest Common Divisor)是最大的d,d能整除a和b。
如果gcd(a,b)=1,我们就称a和b是互素的。
给一个区间[a,b],求与6互素的数的个数。
比如区间[1,10],与6互素的数为1,5,7,所以一共是3个。
输入
第一行是一个整数K(K≤10,000),表示样例的个数。
每个样例占一行,为区间[a,b],(1≤a≤b≤1,000,000,000)
输出
每行输出一个样例的结果
样例输入
2 1 10 1 1000000000
样例输出
3 333333333
很重要的思路就是某一个数(假设为o)除以3,那么得到的就是[1,o]这个区间的能被3整除的数的个数,同理,除以2也如此。但有些数,既能被2整除,又能被3整除,所以要减去。
#include <stdio.h>
#include <stdlib.h>
int gcd(int b) {
int a3 = b / 3;
int a2 = b / 2;
int a6 = b / 6;
return b - (a3 + a2 - a6);
}
int main()
{
int n;
scanf("%d",&n);
while(n--){
int a,b,j,k;
scanf("%d %d",&a,&b);
j=gcd(b);
k=gcd(a-1);
printf("%d\n",j-k);
}
return 0;
}
下面是另外一种解放,比较高效;之后再更新解释;
#include<stdio.h>
int main()
{
int k,a,b,sum,a1,b1,c,d;
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&a,&b);
for(int i=a;;i++)
{
if(i%6==0)
{
a1=i;
break;
}
}
for(int i=b;;i--)
{
if(i%6==0)
{
b1=i;
break;
}
}
c=0;
if(b1>=a1)
{
for(int i=a;i<=a1;i++)
{
if(i%6==1 || i%6==5)
c++;
}
for(int i=b1;i<=b;i++)
{
if(i%6==1 || i%6==5)
c++;
}
printf("%d\n",c+(b1-a1)/6*2);
}
if(a1>b1)
{
for(int i=a;i<=b;i++)
{
if(i%6==1 || i%6==5)
c++;
}
printf("%d\n",c);
}
}
}