【数论】分火腿

题目

【数论】分火腿_第1张图片


有两种切法,像下面这样:
第二种切法是优于第一种的,因为第一种切完之后小部分零件不一定能够平均分下去从而要多切几刀。第二种切着切着可能要切的地方就是这根火腿和另外一根火腿的分界,就少切一刀了。
【数论】分火腿_第2张图片

关于什么时候能少切一刀呢?

每一份为n/m,化简一下为 (n/gcd(n,m) / (m/gcd(n,m) 。使 (一些n/m) 加在一起得到一个整数就可以少切一刀。

已知除以gcd后分数线上下互质,那么凑的整数便是 (上下的最小公倍数/(m/gcd(n,m))

然而这个并没有什么用,我们要的是多少份可以少划一刀即m/gcd(n,m)。

我们把能减少一刀的m/gcd(n,m)份,划为一组,再乘上组数便可以得到答案。


代码

#include
#include
#define ll long long
using namespace std;
ll n,m,ggcd,fen,ans,T;
ll gcd(ll a, ll b){  //寻找最大公倍数
   if(b == 0) return a;
   return gcd(b, a % b); 
}
void work(){
   scanf("%lld%lld", &n, &m);
   ggcd = gcd(n, m);
   fen = m / ggcd;  //得到一组切几段
   ans = (fen - 1) * (m / fen); //一组用的刀数*总共有几组
   printf("%lld\n", ans);
}
int main(){
   scanf("%lld", &T);
   while(T--) work();
}

你可能感兴趣的:(数论)