• 2018.11.1刷题记录


    最近在学新知识,都是例题,比较关键的单独拎出来,其他的就扔代码了。

    P1072 Hankson 的趣味题 (数论)

    题目:

    题目描述
    
    Hanks 博士是 BT(Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。
    
    今天在课堂上,老师讲解了如何求两个正整数c1 c_1c1​ 和 c2c_2c2​ 的最大公约数和最小公倍数。现在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1 a_0,a_1,b_0,b_1a0​,a1​,b0​,b1​,设某未知正整数x xx 满足:
    
    1. xxx 和 a0a_0a0​ 的最大公约数是 a1a_1a1​;
    
    2. xxx 和 b0b_0b0​ 的最小公倍数是b1 b_1b1​。
    
    Hankson 的“逆问题”就是求出满足条件的正整数xxx。但稍加思索之后,他发现这样的xxx 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 xxx 的个数。请你帮助他编程求解这个问题。
    输入输出格式
    输入格式:
    
    第一行为一个正整数 nnn,表示有 nnn 组输入数据。接下来的n nn 行每行一组输入数据,为四个正整数 a0,a1,b0,b1a_0,a_1,b_0,b_1a0​,a1​,b0​,b1​,每两个整数之间用一个空格隔开。输入数据保证 a0a_0a0​ 能被 a1a_1a1​ 整除,b1b_1b1​ 能被b0 b_0 b0​整除。
    
    输出格式:
    
    共 nn n行。每组输入数据的输出结果占一行,为一个整数。
    
    对于每组数据:若不存在这样的 xxx,请输出 000;
    
    若存在这样的x xx,请输出满足条件的x xx 的个数;
    
    输入输出样例
    输入样例#1: 复制
    
    2 
    41 1 96 288 
    95 1 37 1776 
    
    输出样例#1: 复制
    
    6 
    2
    
    说明
    
    【说明】
    
    第一组输入数据,xx x可以是 9,18,36,72,144,2889,18,36,72,144,2889,18,36,72,144,288,共有6 66 个。
    
    第二组输入数据,xxx 可以是48,1776 48,177648,1776,共有 222 个。
    
    【数据范围】
    
    对于 50%的数据,保证有 1≤a0,a1,b0,b1≤100001≤a_0,a_1,b_0,b_1≤100001≤a0​,a1​,b0​,b1​≤10000 且n≤100 n≤100n≤100。
    
    对于 100%的数据,保证有 1≤a0,a1,b0,b1≤2,000,000,0001≤a_0,a_1,b_0,b_1≤2,000,000,0001≤a0​,a1​,b0​,b1​≤2,000,000,000 且 n≤2000n≤2000n≤2000。
    
    NOIP 2009 提高组 第二题
    View Code

    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAX_N = 1e6 + 5;
    
    int prime[MAX_N+1];
    void getPrime() {
        memset(prime, 0, sizeof prime);
        for (int i = 2; i <= MAX_N; i++) {
            if (!prime[i]) prime[++prime[0]] = i;
            for (int j = 1; j <= prime[0] && j <= MAX_N/i; j++) {
                prime[i*j] = 1;
                if (i%j == 0) break;
            }
        }
    }
    
    inline bool work(int p, int&a, int& b, int& c, int& d, long long& ans) {
        int ma = 0, mb = 0, mc = 0, md = 0;
        while (a%p == 0)
            ma++, a /= p;
        while (b%p == 0)
            mb++, b /= p;
        while (c%p == 0)
            mc++, c /= p;
        while (d%p == 0)
            md++, d /= p;
        if (ma > mc && mb < md && mc == md)
            return true;
        else if (ma > mc && mb == md && mc <= md)
            return true;
        else if (ma == mc && mb < md && mc <= md)
            return true;
        else if (ma == mc && mb == md && mc <= md) {
            ans *= md-mc+1;
            return true;
        }
        else {
            ans = 0;
            return false;
        }
    }
    
    int main()
    {
        getPrime();
        int N;
        cin >> N;
        while (N--) {
            int a, b, c, d;
            scanf("%d%d%d%d", &a, &c, &b, &d);
            int maxp = d;
            long long ans = 1;
            for (int i = 1; i <= prime[0] && prime[i]*prime[i] <= maxp; i++) {
                if (d%prime[i]) continue;
                if (!work(prime[i], a, b, c, d, ans))
                    break;
            }
            if (d > 1)
                work(d, a, b, c, d, ans);
            cout << ans << endl;
        }
        return 0;
    }
    /*
    1
    7 1 7 7
    */
    View Code

    更新:

    暴力出奇迹

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline int gcd(int a, int b) {
        return a%b ? gcd(b, a%b) : b;
    }
    
    int divisor[2000];
    void getDivisor(int N) {
        divisor[0] = 0;
        for (int i = 1; (long long)i*i <= N; i++) {
            if (N%i == 0) {
                divisor[++divisor[0]] = i;
                if (N/i != i)
                    divisor[++divisor[0]] = N/i;
            }
        }
    }
    
    int main()
    {
        int n;
        cin >> n;
        while (n--) {
            int a0, a1, b0, b1;
            scanf("%d%d%d%d", &a0, &a1, &b0, &b1);
            getDivisor(b1);
    
            int ans = 0;
            for (int i = 1; i <= divisor[0]; i++) {
                int x = divisor[i];
                int g1 = gcd(x, a0), g2 = (long long)x*b0/gcd(x, b0);
                if (g1 == a1 && g2 == b1)
                    ans++;
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code

    P1463 [POI2002][HAOI2007]反素数 (数论)

    题目:

    题目描述
    
    对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
    
    如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,24,6等都是反质数。
    
    现在给定一个数N,你能求出不超过N的最大的反质数么?
    输入输出格式
    输入格式:
    
    一个数N(1<=N<=2,000,000,000)。
    
    输出格式:
    
    不超过N的最大的反质数。
    
    输入输出样例
    输入样例#1: 复制
    
    1000
    
    输出样例#1: 复制
    
    840
    View Code

    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    #define tomax(a, b) a = a>b?a:b
    #define tomin(a, b) a = a<b?a:b
    const int Prime[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
    
    ll N;
    ll ans, gans;
    void dfs(ll sum, int gsum, int precnt, int i)
    {
        if (i == 10 || sum * Prime[i] > N) {
            if (sum < N) {
                if (gans < gsum)
                    gans = gsum, ans = sum;
                else if (gans == gsum)
                    tomin(ans, sum);
            }
            return;
        }
        for (int j = 1; j <= precnt; j++) {
            sum *= Prime[i];
            if (sum > N)
                break;
            dfs(sum, gsum*(j+1), j, i+1);
        }
    }
    
    int main()
    {
        cin >> N;
        dfs(1, 1, 30, 0);
        cout << ans << endl;
        cout << ans << ' ' << gans << endl;
        return 0;
    }
    View Code

    P2261 [CQOI2007]余数求和 (数论)

    题目:

    题目背景
    
    数学题,无背景
    题目描述
    
    给出正整数n和k,计算G(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数。例如G(10, 5)=5 mod 1 + 5 mod 2 + 5 mod 3 + 5 mod 4 + 5 mod 5 …… + 5 mod 10=0+1+2+1+0+5+5+5+5+5=29
    输入输出格式
    输入格式:
    
    两个整数n k
    
    输出格式:
    
    答案
    
    输入输出样例
    输入样例#1: 复制
    
    10 5
    
    输出样例#1: 复制
    
    29
    
    说明
    
    30%: n,k <= 1000
    
    60%: n,k <= 10^6
    
    100% n,k <= 10^9
    View Code

    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    #define min(a, b) a<b?a:b
    
    ll N, k, ans;
    int main()
    {
        cin >> N >> k;
        ans = N*k;
        for (int x = 1, gx; x <= N; x = gx+1) {
            gx = k/x ? min(k/(k/x), N) : N;
            ans -= (k/x) * (x+gx) * (gx-x+1) / 2;
        }
        cout << ans << endl;
        return 0;
    }
    View Code

    CH3101 阶乘分解 (数论)

    题目:

    描述
    
    给定整数 N(1≤N≤10^6),试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 p_i 和 c_i 即可。
    输入格式
    
    一个整数N。
    输出格式
    
    N! 分解质因数后的结果,共若干行,每行一对pi, ci,表示含有pi^ci项。按照pi从小到大的顺序输出。
    样例输入
    
    5
    
    样例输出
    
    2 3
    3 1
    5 1
    
    样例解释
    
    5! = 120 = 2^3 * 3 * 5
    View Code

    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int MAX_N = 1e6 + 5;
    
    int prime[MAX_N+1];
    void getPrime() {
        memset(prime, 0, sizeof prime);
        for (int i = 2; i < MAX_N; i++) {
            if (!prime[i]) prime[++prime[0]] = i;
            for (int j = 1; j <= prime[0] && prime[j] <= MAX_N/i; j++) {
                prime[prime[j]*i] = 1;
                if (i%prime[j] == 0) break;
            }
        }
    }
    
    int main()
    {
        getPrime();
        int N;
        cin >> N;
        ll cnt;
        for (int i = 1; prime[i] <= N; i++) {
            cnt = 0;
            ll tmp = prime[i];
            while (tmp <= N) {
                cnt += N/tmp;
                tmp *= prime[i];
            }
            cout << prime[i] << ' ' << cnt << endl;
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    顺序表应用4-2:元素位置互换之逆置算法(数据改进)(SDUT 3663)
    顺序表应用3:元素位置互换之移位算法(SDUT 3326)
    Java——容器(Collection)
    Java——容器(Interator)
    Java——JDK1.5新增强的for循环
    Java——容器(Set)
    Java——容器(List)
    Java——类
    Java——面向对象编程
    Java——递归调用
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/9896607.html
Copyright © 2020-2023  润新知