[TJOI2007]跳棋

[TJOI2007]跳棋

题意:

给定一个 \(n \times n\) 的图,有 \(0\)\(1\) 两种点权,每个 \(0\) 能到上下左右同一列/行的下一个 \(0\) ,每个 \(0\) 只能经过一次,给定一个起点,求路径最长。

分析:

因为只能横着/竖着走,因此只能向一个方向拓展。

考虑将走 \(0\) 的情况转变为走 \(1\) ,当向一个方向一直走是 \(1\) 时,说明还没有拓展到能拓展到的点。

因此可以继续走,直到走到 \(0\) 为止,并且增添上贡献。

因为 \(n \leq 100\) ,因此爆搜也能过,直接爆搜即可。

代码:

// P3848 [TJOI2007]跳棋

#include<bits/stdc++.h>

using namespace std;

const int N=105;
const int nx[]={1,-1,0,0},ny[]={0,0,-1,1};
int a[N][N],X,Y,n;
int vis[N][N],ans;


void dfs(int x,int y,int num){
    if(ans<num) ans=num;
    // cout<<ans<<endl;
    vis[x][y]=1;
    for(int i=0;i<4;i++){
        int dx=x+nx[i],dy=y+ny[i];
        int sum=1;
        while(dx>0&&dy>0&&dx<=n&&dy<=n){
            if(a[dx][dy]==1){
                dx+=nx[i]; dy+=ny[i]; sum++;//一直拓展
            }
            else if(sum!=1&&vis[dx][dy]!=1) dfs(dx,dy,num+sum);
            else break;
        }
    }
}

int main(){
    cin>>n>>X>>Y;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&a[i][j]);
    vis[X][Y]=1;
    dfs(X,Y,0);
    cout<<ans<<endl;
    system("pause");
    return 0;
}
posted @ 2021-10-25 18:27  Evitagen  阅读(107)  评论(0编辑  收藏  举报