• NOI2020训练题3 B 最小公倍数


    题目描述:
    (1)(nc)(nc)个数字中删除(n)个,使得剩下(nc−n)个数字。对于这些数字中任意两个不同的数都有一个最小公倍数,请你合理删除这(n)个数字,使得这些最小公倍数中,最小的那个最大。

    输入格式:
    输入文件的第一行是一个正整数(T),表示数据组数。接下来T行每行有两个正整数(n,c),意义如题目所示。

    输出格式:
    输出(T)行正整数,每行有一个答案表示最大的最小(lcm)的值。

    样例输入:

    2
    2 2
    3 2
    

    样例输出:

    12
    12
    

    样例解释与说明:
    在第一组数据中,删去1,2这两个数字,剩下3,4这两个数字。在第二组数据中,删去1,2,6这三个数字,剩下3,4,5这三个数字。

    数据范围:

        对于10%的数据,nc≤16,1≤T≤100.
    
        对于另外20%的数据,n=1,1≤T≤100.
    
        对于另外20%的数据,T=1.
    
        对于另外30%的数据,1≤T≤1000.
    
        对于100%的数据,T≤10^6,1≤n≤10^6,2≤c≤10^6,保证nc−n>1.
    

    时间限制:1s

    空间限制:256MB

    (n = 1)

    首先考虑(n=1),只能删去一个数。

    若不删(1),删(2),答案为(3)

    若删(x(x geq 3)),答案为(2)

    答案只可能为(2)(3)

    若删(1),若(c = 3),则剩下(2,3),答案为(6)

    (c > 3),则剩下(2,3,4, dots),答案为(4)

    (c geq 3)

    考虑 (c geq 3)

    把每(n)个数当成一个集合,记为(S_1,S_2,dots,S_c)

    (S_1)集合内的数不删光,任取(x in S_1),(2^k * x( k in Z) in S_2)

    此时(lcm = 2^k *x in S_2),即(lcm_{ans} in S_2)

    但是删光了(S_1)中的数后,任意两个(S_2)中的数的(lcm)一定不在(S_2)中,因此(lcm_{ans} > 2n)

    所以删去(1 sim n)为最佳。

    考虑(lcm(a,b)(a leq b))的计算,(lcm(a,b) = a * (frac{b}{gcd(a,b)})),显然我们要使(t = frac{b}{gcd(a,b)})最小,因为(t >1),所以(t = 2)时最小,显然(b = 2a)时,(t = 2)

    (c geq 3)时,(b = 2a)是可以取到的,(a = n + 1, b = 2*(n + 1))即为所求,(lcm = 2 * (n + 1))

    (c = 2)

    (c=2)时,(b = 2a)是取不到的,我们考虑(d = b/a)(lcm(a,d * a) = ?)

    首先(1 < d < 2),然后令(d = p/q (gcd(p,q) = 1,p,qin Z)),(lcm(a,d*a) = p * a)

    我们要使(p)尽量小,(p = 3, q = 2)为最小解。

    选取$n + 1 sim 2 * n $中最小的(2)的倍数,乘(3)即可。

    但是(n = 4)时,(6 * frac{3}{2} = 9 > 8)不行,所以特判。

    
    #include<bits/stdc++.h>
    using namespace std;
    
    long long n,c;
    
    int main(){
        int T; scanf("%d",&T);
        while(T --){
            scanf("%lld%lld",&n,&c);
            if(n == 1){
                if(c == 3) printf("6
    ");
                else printf("4
    ");
                continue;
            }
            if(c == 2){
                if(n & 1) printf("%lld
    ",(n + 1) * 3ll);
                else if(n == 4) printf("24
    ");
                else printf("%lld
    ",(n + 2) * 3ll); 
                continue;
            }
            if(c > 2){
                printf("%lld
    ",(n + 1) * 2ll);
                continue;
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    vue系列---identify(生成图片验证码)插件
    vue中的锚链接跳转问题
    vue中怎样实现 路由拦截器
    Vue生命周期和考点
    Vue如何使用vue-area-linkage实现地址三级联动效果
    JS的Key-Val(键值对)设置Key为动态的方法
    web开发——在网页中引用字体包(.ttf),即嵌入特殊字体
    spring boot 实现多个 interceptor 并指定顺序
    BigDecimal加减乘除计算
    乐观锁解决并发问题
  • 原文地址:https://www.cnblogs.com/zzhzzh123/p/13393308.html
Copyright © 2020-2023  润新知