zoukankan      html  css  js  c++  java
  • 2020.1.7 校内测试 T1 分火腿

    题目链接  https://www.luogu.com.cn/problem/U101928

    看了一眼觉得 T1 很水,原来是我想错了,悲惨爆零qwq。 虽然确实挺水的

    嗯,首先看一下题目中的一个细节:

    将 n 根火腿分成均等的 m 份不是 m 段 我就死在了这里 

    也就是说,你可以把两个火腿分成:2/3,1/3,1/3,2/3 四段,其中第二段和第三段可视为一份!

    题解

    既然如此,我们干脆把 n 根火腿看成一大根好了;

    如果我们假设每根火腿的长度为 1,那么这根大火腿的长度为 n;

    我们要将其分成均等的 m 份,那么每一份的长度就都是 n/m;

    考虑到我们砍一刀就多一段,那么我们最多需要砍 m-1 刀;

    还需要注意一个地方:

    这 m-1 刀中有若干刀可能就是火腿的接口,也就是说本来这个地方就是断开的,只不过是我们人为的看成是一段而已,但是我们却花费了 1 刀把它切开。

    所以我们只需再找出这 m-1 刀中有多少刀正好砍在了两根火腿的接口处,用 m-1 一减就是最后答案了。

    可以想到既然有一刀砍在了两根火腿的接口出,那么前面分成的若干段长度为 n/m 的分拼起来可以组成若干根完整的火腿;

    也就是说这个接口处必须同时满足是每一根火腿的长度(1)每一份长度的倍数(n/m) 的倍数,还得是正整数;

    因为前面的若干份是由若干根完整的火腿切来的,必须保证同时是它俩的整数倍数;

    那么我们就先要求出 lcm ( 1,n/m )来 。

    设 k = lcm ( 1,n/m ) = lcm ( m,n ) / m = m * n / gcd ( n,m ) / m = n / gcd ( n,m )

    那么这个长度为 n 的大火腿中有 n / k = n / ( n / gcd ( n,m ) ) = gcd ( n,m ) 个 k 的倍数,也就是有这么些个接口符合要求;

    但是由于 n 也是 k 的倍数,所以我们把最后一刀(砍在了长度为 n 的大火腿的末端的那一刀)给算上了,实际上是不需要的,那么需要减一,也就是:

    gcd ( n,m ) - 1

    最后我们再用 m-1 一减,就是最后的答案了:

    Ans = ( m - 1 ) - ( gcd ( n,m ) - 1 ) = m - gcd ( n,m )

    那么我们直接输出 m - gcd ( n,m ) 就大功告成了!

    Code:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int T,n,m;
    int gcd(int a,int b)
    {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            printf("%d
    ",m-gcd(n,m));
        }
    }
  • 相关阅读:
    Shell编程基础
    lenovo future leaer deveolpmetn program
    求1+2+...+n
    Linux下使用qq
    判断2个线段是否相交
    java大数相加
    Django路由系统
    Django框架
    HTTP协议及Django配置
    mysql索引
  • 原文地址:https://www.cnblogs.com/xcg123/p/12165828.html
Copyright © 2011-2022 走看看