哈理工院赛热身赛 --- 骑士相遇

问题 B: 骑士相遇

时间限制: 1 Sec 内存限制: 32 MB
提交: 22 解决: 4
[ 提交][ 提交状态][ 论坛] [ Edit] [ TestData]

题目描述

Tida非常喜欢玩棋类游戏,他自己发明了一种棋的玩法。这种棋玩法中有两个骑士,骑士这种棋子的移动方式比较特别,一共有四种移动方式:
向前上移动两格然后向左移动两格;
向前上移动两格然后向右移动两格;
向前下移动两格然后向左移动两格;
向前下移动两格然后向右移动两格;
在一个8*8的棋盘上Tida放置了两个骑士,每次将两个骑士按照上述规则同时进行移动,在一些移动后两个骑士可能会同时停留到了同一格子上。为了增加难度,Tida用“#”标记了棋盘上的一些格子,如果两个骑士在在标记的格子上相遇将被视为无效,现在的问题是,对于给定的一个局面,经过一些移动后两个骑士是否可以在非“#”的格子相遇。骑士不能移动到棋盘之外。

输入

多组数据,对于每组数据
包含8行,表示棋盘。
其中“k”表示骑士,“.”表示空地,“#”表示被标记的格子

输出

如果经过一些移动后,两个骑士可以在非“#”的格子相遇,输出YES,否则输出NO。

样例输入

........
........
......#.
...##..#
.......#
...##..#
......#.
K...K...

样例输出

YES

提示

骑士每次移动结束时的相遇才有效,移动过程中的相遇无效。


/*============================================================================= 
# 
#      Author: liangshu - cbam  
# 
#      QQ : 756029571  
# 
#      School : 哈尔滨理工大学  
# 
#      Last modified: 2015-11-16 12:32
# 
#     Filename: H.cpp 
# 
#     Description:  
#        The people who are crazy enough to think they can change the world, are the ones who do !  
=============================================================================*/  
<span style="font-family: Arial, Helvetica, sans-serif;">#include<iostream></span>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
char cnt[10][10];
int s1, t1, s2, t2;
int dir[][2] = {{2, -2}, {2, 2}, {-2, 2}, {-2, -2}};
int vis1[10][10], vis2[10][10];   // 用两个数组标记两匹马的即时状态
// 让正步马先走一步,负步马尾随看能否一步就跟上正步马。开始用一个vis数组标记马状态
//会导致马位置重叠,重叠位置值的步数绝对值相等还好,不相等的话,重新赋值会更改另一匹马的状态
struct Node{
  int x, y, step;
  Node(int x, int y, int z):x(x), y(y), step(z){}
};

bool bfs(){
  memset(vis1, 0, sizeof(vis1));
  memset(vis2, 0, sizeof(vis2));
  queue<Node>q;
  q.push(Node(s1, t1, 1));
  q.push(Node(s2, t2, -1));
  vis1[s1][t1] = 1;
  vis2[s2][t2] = -1;
  while(!q.empty()){
    Node u = q.front();
    q.pop();
    for(int i = 0; i < 4; i++){
        int tx = u.x + dir[i][0];
        int ty = u.y + dir[i][1];
        if(tx >= 0 && tx < 8 && ty >= 0 && ty < 8){
            if(u.step < 0){
                if(vis2[u.x][u.y] - 1 + vis1[tx][ty] == 0 && cnt[tx][ty] != '#'){
                    return true;
                }
                else{
                    vis2[tx][ty] = vis2[u.x][u.y] - 1;
                    q.push(Node(tx, ty, u.step - 1));
                }
            }
            else{
                    vis1[tx][ty] = vis1[u.x][u.y] + 1;
                    q.push(Node(tx, ty, u.step + 1));
            }
            if(abs(vis2[tx][ty]) > 8 || vis1[tx][ty] > 8){//太大会超时的
                return false;
            }
        }
    }
  }
}

int  main(){

   while(scanf("%s", cnt[0]) != EOF){
    int flag = 0;
     for(int i = 0; i < 8; i++){
        if(cnt[0][i] == 'K'){
            flag++;
            s1 = 0; t1 = i;
        }
     }
     for(int i = 1; i < 8; i++){
            scanf("%s", cnt[i]);
        for(int j = 0; j < 8; j++){
            if(cnt[i][j] == 'K'){
                if(!flag){
                    flag++;
                    s1 = i; t1 = j;
                }
                else{
                    flag++;
                s2 = i; t2 = j;
                }
            }
        }
     }
     if(flag == 1){
        printf("YES\n");continue;
     }
     printf("%s\n",bfs() ? "YES" : "NO");
   }
   return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值