DFS P3848 [TJOI2007] 跳棋

发布于:2025-04-02 ⋅ 阅读:(23) ⋅ 点赞:(0)

题目背景

在一个n×n的棋盘上,布满了0和1,如图(a)所示(n=7),为叙述方便,将0用字母表示,如图(b)。

题目描述

跳棋规则:

(1)从某个0格出发,可以向上,下,左,右4个方向连续越过若干个(至少1个)

1格而跳入下一个0格。如图(b)中从A出发,可跳到B,或者到E,但不能直接到K。在跳到B之后还可以继续跳到F;在跳到E之后可继续跳到F或K。直到不能再跳为止。

(2)每个0格只能到达一次,给出的起始点不能再到达,也不能越过。

跳过的距离为跳过1格个数加1,如从A到B,跳过距离为3,从B到F,跳过距离为2。

问 题: 当棋盘和起始点给出之后,问最远能跳的距离是多少?

如上图(b)中,从A出发,可跳过的路线不止一条,其中一条为:

A - B - F - L - K - E (可能不唯一)

3 2 3 3 3

它的距离为14。

输入格式

第一行三个整数 n(1≤n≤100),x,y(起点坐标,上图(b)中A处坐标为1,3)

接下来n行,每行n个数(0或1),数与数之间用一个空格分隔。

输出格式

一个整数,即最大可跳距离(若不能跳,输出0)。

输入输出样例

输入 #1复制

4  3  2
1  0  1  0 
1  1  1  1
0  0  1  0
1  1  0  1

输出 #1复制

6

#include <bits/stdc++.h>
using namespace std;
const int N = 110,INF = 0x3f3f3f3f;

int n,sx,sy,ans;
int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};
bool st[N][N];//走过的路就不能在走
int g[N][N];//存图
//x,y当前走到走到的点 sum表示走到x,y所需要的总步数
void dfs(int x,int y,int sum) {
    if( sum > ans) {
        ans = sum;
    }
    st[x][y] = true;//走过标记
    for(int i = 0 ; i < 4 ;i++ ) {
        int a = x + dx[i];//4个方向
        int b = y + dy[i];
        while(a >= 1 && a <= n && b >= 1 && b <= n && g[a][b]!=0) {
            a += dx[i];//继续沿着这个方向走
            b += dy[i];
        }
        if(a<=0||a>n||b<=0||b>n) continue;
        if(abs(a-x)==1||abs(b-y)==1) continue;//至少越过一个1也就是每次至少走2步
        if(st[a][b])continue;
        dfs(a,b,sum+abs(a-x)+abs(b-y)); //进入下一个点
        st[a][b] = false;
    }
}

int main() {
    cin>>n>>sx>>sy;
    for(int i = 1;i <= n;i++) {
        for (int j = 1; j <= n; j++) {
            cin>>g[i][j];
        }
    }
    dfs(sx,sy,0);
    cout<<ans<<endl;
    return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到