洛谷P7243 最大公约数

思路&题意:

为了方便理解,我们先画个图

在这里插入图片描述
现在就好理解了吧,以x,y为中心每一天就往外扩一层,求x,y=1时是第几天。
代码也是很好写的,只需要在BFS模板中加个__gcd函数求公约数就行了。

Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct point{
	long long x1,y1,step;
}start;
queue<point> dl;
const int N=3e3+5;
int n,m,sx,sy;
ll v[N][N];
ll a[N][N];
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int main(){
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin >> a[i][j];
		}
	}
	cin >> sx >> sy;
	if(a[sx][sy]==1){
		cout<<0;
		return 0;
	}
	start.x1 = sx;
	start.y1 = sy;
	start.step = 1;
	v[start.x1][start.y1] = 1;
	dl.push(start);
	ll sum=a[sx][sy];
	while(!dl.empty()){
		point head = dl.front();
		dl.pop();
		for(int i=0;i<=3;i++){
			int tx=head.x1+dx[i];
			int ty=head.y1+dy[i];
			if(tx<1||tx>n||ty<1||ty>m||v[tx][ty]){
				continue;
			}
			v[tx][ty]=1;
			point temp;
			temp.x1 = tx;
			temp.y1 = ty;
			temp.step = head.step + 1;
			dl.push(temp);
			sum=__gcd(sum,a[tx][ty]);
			if(sum==1){
				cout<<head.step;
				return 0;
			}
		}
	}
	cout<<-1;
	return 0;
}
### 关于最大公约数和最小公倍数问题的解决方案 对于给定两个正整数 \(x_0, y_0 (2 \leq x_0 \leq 100000, 2 \leq y_0 \leq 1000000)\),要找到满足特定条件的正整数对 \(P, Q\) 的数量,其中这些条件是指 \(P, Q\) 应该具有 \(x_0\) 作为它们的最大公约数,并且拥有 \(y_0\) 作为其最小公倍数。 #### 数学关系分析 由于已知两数乘积等于这两个数的最大公约数与最小公倍数之乘积[^1],即: \[ P \times Q = GCD(P,Q) \times LCM(P,Q) \] 因此, \[ P \times Q = x_0 \times y_0 \] 这里的关键在于理解当一对数共享相同的GCD时,则这对数可表示为各自除以其GCD后的互质因子相乘的结果。这意味着如果存在这样的 \(p', q'\) 对应原始的 \(P=x_0\times p'\), \(Q=x_0\times q'\),那么 \(p' * q'=y_0/x_0\) 并且 \(gcd(p', q')=1\)。 #### 枚举方法实现 为了找出所有符合条件的组合,可以通过遍历可能的因数组合来解决问题。具体来说,就是枚举所有的 \(d|(\frac{y_0}{x_0})\) (即能被 \((\frac{y_0}{x_0})\) 整除),并检查每一对是否满足 gcd 等于 1 的条件。这样做的效率取决于优化过的素数筛选以及快速判断两个数之间是否存在公共因子的技术。 下面是 Python 实现的一个简单例子: ```python from math import gcd def count_pairs(x0, y0): result = [] ratio = y0 // x0 for i in range(1, int(ratio ** 0.5)+1): if ratio % i == 0: j = ratio // i # Check coprime condition and avoid duplicate pairs. if gcd(i, j) == 1: pair1 = sorted([i*x0, j*x0]) if not any(set(pair1)==set(item) for item in result): result.append(pair1) # Avoid square root case being counted twice. if i != ratio//i and gcd(j, i) == 1: pair2 = sorted([j*x0, i*x0]) if not any(set(pair2)==set(item) for item in result): result.append(pair2) return len(result) print(count_pairs(int(input()), int(input()))) ``` 这段代码首先定义了一个辅助函数 `count_pairs` 接受参数 `x0`, `y0` 表示题目中的输入值。接着通过循环迭代寻找合适的配对 `(i,j)` ,确保两者之间的比例正好是目标比率 `\frac{y_0}{x_0}` 。最后返回符合条件的不同有序对的数量。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值