打卡信奥刷题(2034)用C++实现信奥 P11130 【MX-X5-T2】「GFOI Round 1」Interstellar

P11130 【MX-X5-T2】「GFOI Round 1」Interstellar

题目背景

原题链接:https://oier.team/problems/X5C


Interstellar - PIKASONIC

题目描述

你有一个正整数 x x x,你可以对它进行如下操作:

  • 选择一个正整数 y y y,把 x x x 变为它的 gcd ⁡ ( x , y ) \gcd(x, y) gcd(x,y) 倍,即 x ← x × gcd ⁡ ( x , y ) x \gets x \times \gcd(x, y) xx×gcd(x,y)
    gcd ⁡ ( x , y ) \gcd(x, y) gcd(x,y) 表示 x , y x, y x,y 的最大公因数。)

x x x 的初始值为 n n n,你想通过若干次操作(也可不操作)将它变为 m m m。你想知道至少要多少次操作才能达成目标,或报告无解。

输入格式

本题有多组测试数据。

第一行输入一个正整数 T T T,表示测试数据组数。

对于每组测试数据:

第一行包含两个正整数 n , m n, m n,m

输出格式

对于每组数据:

  • 若无解,即 x x x 无论如何操作都不能变成 m m m,输出 − 1 -1 1
  • 否则输出一行一个非负整数,表示最小的操作次数。

输入输出样例 #1

输入 #1

6
1 1
2 4
2 6
12 288
30 144000
114 5141919810

输出 #1

0
1
-1
2
3
-1

说明/提示

【样例解释】

对于第一组数据,无需进行任何操作,答案是 0 0 0

对于第二组数据,可以选择 y = 6 y = 6 y=6,那么 x x x 会变成 2 × gcd ⁡ ( 2 , 6 ) = 4 2 \times \gcd(2, 6) = 4 2×gcd(2,6)=4

对于第三组数据,容易证明无论如何进行操作都不可能达成目标,所以输出 − 1 -1 1

对于第四组数据,可以:

  • 选择 y = 16 y = 16 y=16,那么 x x x 会变成 12 × gcd ⁡ ( 12 , 16 ) = 48 12 \times \gcd(12, 16) = 48 12×gcd(12,16)=48
  • 选择 y = 6 y = 6 y=6,那么 x x x 会变成 48 × gcd ⁡ ( 48 , 6 ) = 288 48 \times \gcd(48, 6) = 288 48×gcd(48,6)=288

【数据范围】

测试点编号 n ≤ n \le n m ≤ m \le m分值
1 1 1 100 100 100 2 × 1 0 3 2 \times 10^3 2×103 21 21 21
2 2 2 2 2 2 1 0 18 10^{18} 1018 17 17 17
3 3 3 1 0 5 10^5 105 1 0 5 10^5 105 14 14 14
4 4 4 1 0 7 10^7 107 1 0 7 10^7 107 16 16 16
5 5 5 1 0 18 10^{18} 1018 1 0 18 10^{18} 1018 32 32 32

对于所有数据,满足 1 ≤ T ≤ 2 × 1 0 5 1 \le T \le 2 \times 10^5 1T2×105 1 ≤ n ≤ m ≤ 1 0 18 1 \le n \le m \le 10^{18} 1nm1018

C++实现

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t;
ll n,m;
inline ll gcd(ll a,ll b)
{
	while(b^=a^=b^=a%=b);
	return a;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld%lld",&n,&m);
		if(m%n)
		{
			puts("-1");
			continue;
		}
		ll d=m/n,ans=0;
		while(1)
		{
			ll g=gcd(n,d);
			if(g==1) break;
			d/=g,n*=g,ans++;
		}
		if(d>1) puts("-1");
		else printf("%lld\n",ans);
	}
	return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值