G. GCD on a grid

原题链接

题解

  1. \(gcd\) 一定能被 \(a[1][1],a[n][m]\) 整除
    2.\(gcd\) 能被通过的路径上所有元素整除
    由此分析:遍历 \([1,\sqrt{gcd(a[1][1],a[n][m])}]\) 判断能否通过(被路径上所有元素整除)

我还在思考是广搜还是深搜,由于起点终点已知,求是否存在该路径,所以深搜

有一个逆天优化请看代码

code

#include<bits/stdc++.h>
using namespace std;

int a[105][105];
int vis[105][105]={0};
int n,m;
int dfs(int len,int x,int y)
{
    vis[x][y]=len;//代表gcd=len时走到过这里,太巧妙了!!
    if(a[x][y]%len!=0) return 0;
    if(x==n&&y==m) return 1;
    int ans=0;
    if(y+1<=m&&vis[x][y+1]!=len) ans|=dfs(len,x,y+1);
    if(x+1<=n&&vis[x+1][y]!=len) ans|=dfs(len,x+1,y);

    return ans;
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;

        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>a[i][j];
            }
        }

        int maxs=__gcd(a[1][1],a[n][m]),ans=1;
        for(int k=1;k*k<=maxs;k++)
        {
            if(maxs%k==0)
            {
                if(dfs(maxs/k,1,1))
                {
                    ans=maxs/k;
                    break;
                }
                else
                {
                    if(dfs(k,1,1)) ans=k;
                }
            }
        }
        cout<<ans<<endl;
        memset(vis,0,sizeof vis);//但是每个测试用例用完还是要清零,不然下一回合遇到时会退出
    }
    return 0;
}

posted @ 2024-04-10 16:49  纯粹的  阅读(138)  评论(0)    收藏  举报