zoukankan      html  css  js  c++  java
  • NOIP2009 Hankson 的趣味题 : 数论

    题目描述

    Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。

    今天在课堂上,老师讲解了如何求两个正整数 c1 和 c2 的最大公约数和最小公倍数。现在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数 a0,a1,b0,b1,设某未知正整数 x 满足:

    1. x 和 a0 的最大公约数是 a1;

    2. x 和 b0 的最小公倍数是 b1。

    Hankson 的“逆问题”就是求出满足条件的正整数 x。但稍加思索之后,他发现这样的x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮助他编程求解这个问题。

    输入输出格式

    输入格式:

    第一行为一个正整数 n,表示有 n 组输入数据。接下来的 n 行每行一组输入数据,为四个正整数 a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入数据保证 a0 能被 a1 整除,b1 能被 b0 整除。

    输出格式:

    输出文件 son.out 共 n 行。每组输入数据的输出结果占一行,为一个整数。

    对于每组数据:若不存在这样的 x,请输出 0;

    若存在这样的 x,请输出满足条件的 x 的个数;

    输入输出样例

    输入样例#1: 
    2 
    41 1 96 288 
    95 1 37 1776 
    输出样例#1: 
    6 
    2

    说明

    【说明】

    第一组输入数据,x 可以是 9、18、36、72、144、288,共有 6 个。

    第二组输入数据,x 可以是 48、1776,共有 2 个。

    【数据范围】

    对于 50%的数据,保证有 1≤a0,a1,b0,b1≤10000 且 n≤100。

    对于 100%的数据,保证有 1≤a0,a1,b0,b1≤2,000,000,000 且 n≤2000。

    NOIP 2009 提高组 第二题

    // 来源:洛谷

    进行一波数学推导:

    gcd(x, a0) = a1

    —> x = k1 * a1,    a0 = k 2 * a1;

    —> gcd(k1, k2) = 1

      pf : 假设gcd(k1, k2) != 1;

        设K = gcd(k1, k2);

        ->k1 = K * p,   k2 = K * q;

        ->x = p * K * a1,   a0 = q * K * a1;

        ->gcd(x, a0) = K * a1 != a1;

         假设不成立;

    所以 : gcd(x, y) = k  -> gcd(x / k , y / k ) = 1;

    gcd(x / a1, a0 / a1) = 1;

    接着

    lcm(x, b0) * gcd(x, b0) = x * b0;

    —> gcd(x, b0) = x * b0 / b1;

    —> gcd(b1 / b0 , b1 / x) = 1;

    仔细研究上面的两个等式 : x 是 a1 的倍数, x 是 b1 的约数;

    可以枚举b1的约数, 然后判断上边两个等式, 成立就++;

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define ing long long 
    
    int T, n;
    int a0, a1, b0, b1;
    
    
    int Gcd(int x, int y)
    {
        return y == 0 ? x : Gcd(y, x % y);
    }
    
    signed main()
    {
        cin >> T;
        while(T--)
        {
            int cnt = 0;
            scanf("%lld%lld%lld%lld", &a0, &a1, &b0, &b1);
            
            
            for(register int i = 1 ; i * i <= b1 ; i ++)
            {
                if(b1 % i != 0) continue;
                
                int g = Gcd(i / a1 , a0 / a1);
                int gg = Gcd(b1 / b0, b1 / i);
                
                if(i % a1 == 0 && g == 1 && gg == 1) 
                {
                    cnt++;
                }
                
                int j = b1 / i;
                
                if(i == j) continue;
                
                
                int c = Gcd(j / a1, a0 / a1);
                int cc = Gcd(b1 / b0, b1 / j);
                
                if(j % a1 == 0 && c == 1 && cc == 1) cnt++;
                
            }
            
            printf("%lld\n", cnt);
        }
        return 0;
        
    }
    zZhBr
  • 相关阅读:
    Jmeter混合场景压力测试
    数据驱动DDT(Data-Driven Tests):测试数据的参数化
    运用TextSuite和TestRunner运行测试脚本
    Test Fixture框架结构
    解决appium-doctor报各种 cannot be found问题
    搭建python+appium环境的时候遇到 'could not find adb.exe!'的问题
    Python appium搭建app自动化测试环境
    夜神模拟器查看APP的activity等信息
    [leetcode 23]Merge k Sorted Lists
    [leetcode 22]generate parentheses
  • 原文地址:https://www.cnblogs.com/BriMon/p/8933845.html
Copyright © 2011-2022 走看看