ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2020.1.7 校内测试 T1 分火腿

2020-01-08 12:03:48  阅读:219  来源: 互联网

标签:校内 gcd int 2020.1 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\n",m-gcd(n,m));
    }
}

标签:校内,gcd,int,2020.1,T1,倍数,长度,火腿,我们
来源: https://www.cnblogs.com/xcg123/p/12165828.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有