gcd3014
问题描述
小明和小红是一对恋人,他们相爱已经三年了,在今年的七夕节,小明准备给小红一个特殊的礼物。他想要送给小红一些数字,让小红算出有多少对正整数 (a,b) 满足以下条件:
c×lcm(a,b)−d×gcd(a,b)=x其中 c,d,x 是小明给出的数gcd(a,b) 为 a,b 的最大公因lcm(a,b) 为 a,b 的最小公倍数 。
小明希望这个问题能够考察小红对于数论基础知识的理解和运用,同时也希望小红能够在这个特殊的日子里感受到他对她的深情。请你帮助小明实现他的想法吧!
输入格式
第一行包含一个正整数 T(1≤T≤103),表示询问的组数。
接下来 T 行,每行包含三个正整数 c,d,x(1≤c,d,x≤105)。
输出格式
对于每组询问,输出一个正整数表示满足条件的(a,b) 对数。
样例输入
2
2 3 6
4 5 7
样例输出
4
2
解析
需要理解gcd(最大公因数)和lcm(最小公倍数)的性质,并且能够遍历所有可能的正整数对(a, b),计算满足条件的数量。然而,直接遍历所有可能的(a, b)对会导致时间复杂度过高,因此我们需要观察题目中所给的不等式。
代码
package lanqiaoyun; import java.util.*; public class gcd3014 { public static void main(String args[]) { Scanner scanner=new Scanner(System.in); int T = scanner.nextInt(); while (T-- > 0) { int c = scanner.nextInt(); int d = scanner.nextInt(); int x = scanner.nextInt(); System.out.println(countPairs(c, d, x)); } scanner.close(); } private static int countPairs(int c, int d, int x) { int count = 0; // gcd中所有的可能的元素 for (int g = 1; g * g <= x; g++) { if (x % g != 0) continue; // Skip if g does not divide x int n = (x + d * g) / c; // 计算a*b if (n % g != 0) continue; // Skip if g does not divide n int phi = eulerPhi(n / g); // Calculate phi(n/g), the count of numbers coprime with n/g count += phi; // Add phi(n/g) to the count for each valid g } return count; } // Calculate Euler's totient function phi(n) private static int eulerPhi(int n) { int result = n; for (int i = 2; i * i <= n; i++) { if (n % i == 0) { while (n % i == 0) { n /= i; } result -= result / i; } } if (n > 1) { result -= result / n; } return result; } public static long gcd(long a,long b) { return b==0?a:gcd(b,a%b); } public static long lcm(long a,long b) { return a/gcd(a,b)*b; } }
gcd368
在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果。例如,对某一观点表示支持的有 1498 人,反对的有 902 人,那么赞同与反对的比例可以简单的记为 1498:902。
不过,如果把调查结果就以这种方式呈现出来,大多数人肯定不会满意。因为这个比例的数值太大,难以一眼看出它们的关系。对于上面这个例子,如果把比例记为 5:3,虽然与真实结果有一定的误差,但依然能够较为准确地反映调查结果,同时也显得比较直观。
现给出支持人数 A,反对人数 B,以及一个上限 L,请你将 A 比 B 化简为 ′A′ 比 ′B′,要求在 ′A′和 ‘B′均不大于 L 且 ′A′和 ′B′互质(两个整数的最大公约数是 1)的前提下,A′/B′≥A/B且A′/B′−A/B 的值尽可能小。
输入描述
输入共一行,包含三个整数 A,B,L,每两个整数之间用一个空格隔开,分别表示支持人数、反对人数以及上限。
其中,1≤A≤106,1≤B≤106,1≤L≤100,A/B≤L。
输出描述
输出共一行,包含两个整数 ′A′,B′,中间用一个空格隔开,表示化简后的比例。
输入输出样例
示例
输入
1498 902 10
输出
5 3
代码
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
double a=scan.nextDouble();
double b=scan.nextDouble();
double l=scan.nextDouble();
double min=100;
int res1=0;
int res2=0;
for(int i=0;i<l;i++){
for(int j=1;j<l;j++){
double m=(double) a*1.0/b;
double p=(double) i*1.0/j;
if(p>=m&&gcd(i,j)==1&&p-m<=min){
min=(p-m);//持续寻找更小的min,并更新
res1=i;
res2=j;
}
}
}
if(l==1) {
res1=1;
res2=1;
System.out.println(res1+" "+res2);
}else {
System.out.println(res1+" "+res2);
}
scan.close();
}
public static double gcd(double a,double b ){
return b==0?a:gcd(b,a%b);
}
}
gcd520
题目描述
Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。
今天在课堂上,老师讲解了如何求两个正整数c1 和 c2 的最大公约数和最小公倍数。现在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1,设某未知正整数 x 满足:
-
x 和 a0 的最大公约数是 a1;
-
x 和 b0 的最小公倍数是 b1。
Hankson 的“逆问题”就是求出满足条件的正整数 x。但稍加思索之后,他发现这样的 x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮助他编程求解这个问题。
输入描述
第一行为一个正整数 n,表示有 n 组输入数据。
接下来的 n 行每行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入数据保证 a0 能被 a1 整除,b1 能被 b0 整除。
其中,保证有1≤a0,a1,b0,b1≤2×109且n≤2000。
输出描述
输出共 n 行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的 x,请输出 0;若存在这样的 x,请输出满足条件的 x 的个数;
输入输出样例
示例 1
输入
2
41 1 96 288
95 1 37 1776
输出
6
2
代码
package lanqiaoyun;
import java.util.*;
public class gcd520 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int n=scan.nextInt();
while(n-->0){
long a0=scan.nextLong();
long a1=scan.nextLong();
long b0=scan.nextLong();
long b1=scan.nextLong();
int count=0;
for(int x=0;x<=b1;x++){
if(gcd(x,a0)==a1&&lcm(x,b0)==b1){
count++;
}
}
System.out.println(count);
}
scan.close();
}
public static long gcd(long x,long a0){
return a0==0?x:gcd(a0,x%a0);
}
public static long lcm(long x,long b0){
return x/gcd(x,b0)*b0;
}
}
(后期持续更新)