2021,06.13 洛谷 P7243 最大公约数

本文介绍了洛谷P7243题目,讨论了数在特定条件下的传染性质,即当某位置的数为1时,会使其周围未变为1的数在第二天变为1。如果初始状态存在gcd为1的情况,该点将在第一天变为1并开始传染。若无这种情况,答案为-1。解决问题的方法是使用动态规划,记录每个位置变成1的天数,初始为1的点答案为0。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

luogu P7243\color{green}{\texttt{luogu P7243}}luogu P7243

[Problem]\color{blue}{\texttt{[Problem]}}[Problem]

在这里插入图片描述

[Solution]\color{blue}{\texttt{[Solution]}}[Solution]

稍微思考一下,就可以得到如下的性质:

  1. 如果一个位置 (x,y)(x,y)(x,y) 上的数变成了 111,那么第二天它四周围尚未变成 111 的数都会变成 111。(可以形象地理解为 111 会传染)
  2. 如果一个位置 (x,y)(x,y)(x,y)初始状态下与它四周的数的 gcd⁡\gcdgcd 值为 111,那么它在第一天就会变成 111。从第二天开始,它就会开始传染四周。
  3. 如果初始转台下不存在如 222 所说的点,那么,答案就是 −1-11

所以,我们可以用 bfs 来解决这道题。开一个数组保存每个点会在第几天变成 111 即可。

注意,如果初始就是 111,那么这个点的答案应该是 000

[code]\color{blue}{\texttt{[code]}}[code]

int times[2010][2010];
bool visit[2010][2010];
ll a[2010][2010];int n,m;
inline ll gcd(ll u,ll v){
	if (v==0) return u;
	else return gcd(v,u%v);
}
struct node{int x,y;};
inline bool check(int x,int y){
	return (x>0&&x<=n)&&(y>0&&y<=m);
}
inline bool First(int x,int y){
	register ll g=a[x][y];//最大公因数 
	if (check(x-1,y)) g=gcd(g,a[x-1][y]);
	if (check(x,y-1)) g=gcd(g,a[x][y-1]);
	if (check(x+1,y)) g=gcd(g,a[x+1][y]);
	if (check(x,y+1)) g=gcd(g,a[x][y+1]);
	return g==1;
}
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
inline void bfs(){
	queue<node> q;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if (First(i,j)){
				q.push((node){i,j});
				times[i][j]=(a[i][j]!=1);
				visit[i][j]=false;
			}
	while (!q.empty()){
		node z=q.front();q.pop();
		for(int i=0;i<4;i++){
			int x=z.x+dx[i],y=z.y+dy[i];
			if (!check(x,y)) continue;
			if (!visit[x][y]) continue;
			times[x][y]=times[z.x][z.y]+1;
			q.push((node){x,y});
			visit[x][y]=false;
		}
	}
}
int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			a[i][j]=read();
	memset(times,-1,sizeof(times));
	memset(visit,true,sizeof(visit));
	bfs();//利用 bfs 求解答案 
	int l=read(),r=read();
	printf("%d",times[l][r]);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值