contest 1 H

题目的大意是:今天小云和小塘玩起了跳格子的游戏,小云对小塘说:
我在地上给你画一些格子,格子里面会出现下面的这些符号
‘S’ 表示你要从这个格子开始
‘X’ 表示这个格子不能跳
‘.’ 表示这个格子可以跳
‘D’ 表示跳到这个格子就结束了
然后我告诉你要跳的步数,每跳一格算一步,你能恰好跳到终点吗?
Input
输入包含多组测试数据,每组测试数据的第一行有三个数N,M,S (1 < N, M < 7;0 < S< 50),

分别表示格子的行数、列数和走的步数。当N,M,S均为0 时表示输入结束。

Output
如果能刚跳走到终点,输出YES ,不能则输出NO 。

这道题有一点要恨注意,就是从矩阵中的一个点到另一个点的路径长度的奇偶性是一定

还有如果要用DFs的话,一定注意这是一个回溯的过程,要标记的

Bfs代码如下(最短路径,判断最短路径和s的关系,关系包括大小和奇偶)

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int N = 10;
const int INF = 1000000;
int n, m, s;
int g[N][N], d[10][10];
struct node {
    int i, j;
};

void bfs( int s1, int s2 ) {
   node no;
   queue <node> q;
   no.i = s1, no.j = s2;
   q.push(no);
   bool vis[N][N];
   memset(vis, 0, sizeof(vis) );
   for ( int i = 0; i < n; ++i ) for ( int j = 0; j < m; ++j ) d[i][j] = INF;
   d[s1][s2] = 0;
   vis[s1][s2] = true;
   while ( !q.empty() ) {
       node u = q.front(); q.pop();
       int x = u.i, y = u.j;
       if ( g[x][y] == 'D' ) break;
       if ( x > 0 && !vis[x-1][y] && g[x-1][y] != 'X' && d[x-1][y] > d[x][y] + 1 ) { 
           no.i = x-1, no.j = y; 
           q.push(no); vis[x-1][y] = 1;
           d[x-1][y] = d[x][y] + 1;
       }
       if ( y > 0 && !vis[x][y-1] && g[x][y-1] != 'X' && d[x][y-1] > d[x][y] + 1 ) { no.i = x, no.j = y-1; q.push(no); vis[x][y-1] = 1; d[x][y-1] = d[x][y] + 1;}
       if ( x < n-1 && !vis[x+1][y] && g[x+1][y] != 'X' && d[x+1][y] > d[x][y] + 1 ) { no.i = x+1, no.j = y; q.push(no); vis[x+1][y] = 1;d[x+1][y] = d[x][y] + 1;}
       if ( y < m-1 && !vis[x][y+1] && g[x][y+1] != 'X' && d[x][y+1] > d[x][y] + 1 ) { no.i = x, no.j = y+1; q.push(no); vis[x][y+1] = 1;d[x][y+1] = d[x][y] + 1;}
   }
}
int main() 
{
    while ( scanf("%d%d%d", &n, &m, &s) != EOF && ( n || m || s ) ) {
        getchar();
        int s1, s2, e1, e2;
        for ( int i = 0; i < n; getchar(), ++i )
            for ( int j = 0; j < m; ++j ) {
                scanf("%c", &g[i][j]);
                if ( g[i][j] == 'S' ) s1 = i, s2 = j;
                if ( g[i][j] == 'D' ) e1 = i, e2 = j;
            }
        bfs(s1, s2);
        //printf("%d\n", d[e1][e2]);
        if ( d[e1][e2] > s || ( s%2 ) != ( d[e1][e2]%2 ) ) printf("NO\n");
        else printf("YES\n");
    }
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值