题解:P16343 [科大国创杯初中组 2026] 行走/ARIS0_0 - 16
P16343 [科大国创杯初中组 2026] 行走
思路
注意到 gcd 操作定然不会使得结果变大,且每次操作定然为前驱所有节点 gcd 后的约数
,所以我们其答案必然为
Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define lowbit(x) (x&(-x))
#define ls (u<<1)
#define rs (u<<1|1)
#define pii pair<int,int>
#define all(v) v.begin(),v.end()
int read(){
int k=0,f=1;
char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') k=k*10+c-'0',c=getchar();
return k*f;
}
void write(int x){
if(x<0) putchar('-'),x=-x;
if(x<10) putchar(x+'0');
else write(x/10),putchar(x%10+'0');
}
const int N=1010;
int a[N][N];
bool dp[N][N];
vector<int> v;
void solve(){
int n=read(),V=read();
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++) a[i][j]=read();
}
V=__gcd(a[1][1],a[n][n]);
for (int i=1;i<=V;i++){
if (V%i==0) v.push_back(i);
}
sort(v.begin(),v.end(),greater<int>());
for (int x:v){
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++) dp[i][j]=0;
}
dp[1][1]=dp[0][0]=dp[1][0]=dp[0][1]=1;
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (a[i][j]%x==0) dp[i][j]=dp[i-1][j]|dp[i][j-1];
}
}
if (dp[n][n]){
write(x);
break;
}
}
}
signed main(){
int T=1;
while (T--) solve();
return 0;
}
// ARIS0_0 16 祝好