象棋 UVa1589

看到这个题目基本的想法是,将黑将能走的四个方向都遍历一遍,然后再判断判断红方能否吃掉它。如果所有可能的走向都会被将死,则黑将被将死。需要注意越界,吃子,和马被别脚的情况。附上一张自己画的一张简图可能会清楚一些:

  
思路导图

下面贴一下代码,更详细的解释在代码的注释里,代码有点冗长,有能力的可以把相同的地方写成函数(比如说帅和车的判断是可以放一起的)
#include<iostream>
#include<fstream>
using namespace std;
struct qizhi
{
    char kind;
    int row;
    int column;
};

int panduan(int b_row, int b_column, int size, const qizhi*  p)   //用来判断黑将走某一步会不会被将死,如果会死返回0,不会返回1
{
    for (int i = 0; i < size; ++i)
    {
        switch (p[i].kind)
        {
        case 'G':
            if (p[i].column == b_column)
            {
                int key = 0;   //标记,
                for (int j = 0; j < size; ++j)    //如果黑将和红帅在同列,判断中间有没有其他的旗子
                {
                    if (j == i)
                        continue;
                    if (p[j].column == p[i].column&&p[j].row > b_row&&p[j].row < p[i].row)
                    {
                        key = 1;
                        break;
                    }
                }
                if (0 == key)
                    return 0;            //如果key为0,表面被将死直接返回0
            }
            break;
        case 'R':
            if (p[i].column == b_column)
            {
                int key = 0, key1;   //标记,
                p[i].row > b_row ? key1 = 1 : key1 = 0;
                for (int j = 0; j < size; ++j)    //如果黑将和车在同列,判断中间有没有其他的旗子
                {
                    if (j == i)
                        continue;
                    if (key1 == 1)
                    {
                        if (p[j].column == p[i].column&&p[j].row > b_row&&p[j].row < p[i].row)
                        {
                            key = 1;
                            break;
                        }
                    }
                    else
                    {
                        if (p[j].column == p[i].column&&p[j].row <b_row&&p[j].row > p[i].row)
                        {
                            key = 1;
                            break;
                        }
                    }

                }
                if (0 == key)
                    return 0;            //如果key为0,表明被将死直接返回0
            }
            if (p[i].row == b_row)
            {
                int key = 0, key1;   //标记,
                p[i].column > b_column ? key1 = 1 : key1 = 0;
                for (int j = 0; j < size; ++j)    //如果黑将和车在同行,判断中间有没有其他的旗子
                {
                    if (j == i)
                        continue;
                    if (key1 == 1)
                    {
                        if (p[j].row == p[i].row&&p[j].column > b_column&&p[j].column < p[i].column)
                        {
                            key = 1;
                            break;
                        }
                    }
                    else
                    {
                        if (p[j].row == p[i].row&&p[j].column < b_column&&p[j].column > p[i].column)
                        {
                            key = 1;
                            break;
                        }
                    }

                }
                if (0 == key)
                    return 0;            //如果key为0,表明被将死直接返回0
            }
            break;
        case 'C':
            if (p[i].column == b_column)
            {
                int key = 0, key1;   //标记,
                p[i].row > b_row ? key1 = 1 : key1 = 0;
                for (int j = 0; j < size; ++j)    //如果黑将和炮在同列,判断中间有多少个旗子
                {
                    if (j == i)
                        continue;
                    if (1 == key1)
                    {
                        if (p[j].column == p[i].column&&p[j].row > b_row&&p[j].row < p[i].row)
                        {
                            key += 1;
                        }
                    }
                    else
                    {
                        if (p[j].column == p[i].column&&p[j].row<b_row&&p[j].row>p[i].row)
                        {
                            key += 1;
                        }
                    }

                }
                if (1 == key)
                    return 0;            //如果key为1,表明被将死直接返回0
            }
            if (p[i].row == b_row)
            {
                int key = 0, key1;   //标记,
                p[i].column > b_column ? key1 = 1 : key1 = 0;
                for (int j = 0; j < size; ++j)    //如果黑将和炮在同行,判断中间有多少个旗子
                {
                    if (j == i)
                        continue;
                    if (1 == key1)
                    {
                        if (p[j].row == p[i].row&&p[j].column > b_column&&p[j].column < p[i].column)
                        {
                            key += 1;
                        }
                    }
                    else
                    {
                        if (p[j].row == p[i].row&&p[j].column<b_column&&p[j].column>p[i].column)
                        {
                            key += 1;
                        }
                    }
                }
                if (1 == key)
                    return 0;            //如果key为1,表明被将死直接返回0
            }
            break;
         case 'H':
            int up = 0, down = 0, left = 0, right = 0;
            for (int j = 0; j < size; ++j)    //判断向上是否会别马脚
            {
                if (j == i)
                    continue;
                if (p[j].row == p[i].row - 1 && p[j].column == p[i].column)
                {
                    up = 1;
                    break;                          //如果别马脚,就结束
                }
            }
            if (0 == up)
            {
                if (p[i].column - 1 == b_column&&p[i].row - 2 == b_row)
                    return 0;
                else if (p[i].column + 1 == b_column&&p[i].row - 2 == b_row)
                    return 0;
            }
            for (int j = 0; j < size; ++j)    //判断向左是否会别马脚
            {
                if (j == i)
                    continue;
                if (p[j].row == p[i].row && p[j].column == p[i].column - 1)
                {
                    left = 1;
                    break;                          //如果别马脚,就结束
                }
            }
            if (0 == left)
            {
                if (p[i].column - 2 == b_column&&p[i].row - 1 == b_row)
                    return 0;
                else if (p[i].column - 2 == b_column&&p[i].row + 1 == b_row)
                    return 0;
            }
            for (int j = 0; j < size; ++j)    //判断向右是否会别马脚
            {
                if (j == i)
                    continue;
                if (p[j].row == p[i].row && p[j].column == p[i].column + 1)
                {
                    right = 1;
                    break;                          //如果别马脚,就结束
                }

            }
            if (0 == right)
            {
                if (p[i].column + 2 == b_column&&p[i].row - 1 == b_row)
                    return 0;
                else if (p[i].column + 2 == b_column&&p[i].row + 1 == b_row)
                    return 0;
            }
            for (int j = 0; j < size; ++j)    //判断向下是否会别马脚
            {
                if (j == i)
                    continue;
                if (p[j].row == p[i].row + 1 && p[j].column == p[i].column)
                {
                    down = 1;
                    break;                          //如果别马脚,就结束
                }

            }
            if (0 == down)
            {
                if (p[i].column - 1 == b_column&&p[i].row + 2 == b_row)
                    return 0;
                else if (p[i].column + 1 == b_column&&p[i].row + 2 == b_row)
                    return 0;
            }
            break;


        }
    }
    return 1;
}

int yes_or_no(int b_row, int b_column, int size, qizhi*  p)               //判断有没有被将死,将死返回false,没死返回true
{
    int up = 0, down = 0, left = 0, right = 0;
    if (b_row - 1 > 0)                         //判断向上走会不会死
    {
        for (int i = 0; i < size; ++i)
        {
            if (p[i].column == b_column&&p[i].row == b_row - 1)      //判断黑将去的地方有没有红棋的子如果有吃掉
            {
                p[i].kind = ' ';
                break;
            }
        }
        up = panduan(b_row - 1, b_column, size, p);
    }
    if (b_row + 1 < 4)                                   //判断向下走会不会死
    {
        for (int i = 0; i < size; ++i)
        {
            if (p[i].column == b_column&&p[i].row == b_row + 1)      //判断黑将去的地方有没有红棋的子如果有吃掉
            {
                p[i].kind = ' ';
                break;
            }
        }
        down = panduan(b_row + 1, b_column, size, p);
    }
    if (b_column - 1 > 3)                               //判断向左走会不会死
    {
        for (int i = 0; i < size; ++i)
        {
            if (p[i].column == b_column - 1 && p[i].row == b_row)      //判断黑将去的地方有没有红棋的子如果有吃掉
            {
                p[i].kind = ' ';
                break;
            }
        }
        left = panduan(b_row, b_column - 1, size, p);
    }
    if (b_column + 1 < 7)                       //判断向右走会不会死
    {
        for (int i = 0; i < size; ++i)
        {
            if (p[i].column == b_column + 1 && p[i].row == b_row)      //判断黑将去的地方有没有红棋的子如果有吃掉
            {
                p[i].kind = ' ';
                break;
            }
        }
        right = panduan(b_row, b_column + 1, size, p);
    }
    return up + down + left + right;
}

int main()
{
    ///*文件重定向,输出测试*/
    //ifstream fin;
    //fin.open("data.in");
    //cin.rdbuf(fin.rdbuf());
    //ofstream out;
    //out.open("data.out");
    //cout.rdbuf(out.rdbuf());
    int r_number = 0, b_row = 0, b_column = 0;        //红方棋字个数,黑方将的位置
    while (cin >> r_number >> b_row >> b_column&&r_number != 0 && b_column != 0 && b_row != 0)
    {
        auto p = new qizhi[r_number];
        for (int i = 0; i < r_number; ++i)
        {
            cin >> p[i].kind >> p[i].row >> p[i].column;
        }
        if (yes_or_no(b_row, b_column, r_number, p))
            cout << "NO" << endl;
        else
            cout << "YES" << endl;
        delete[] p;

    }


}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,945评论 25 707
  • 所有知识点已整理成app app下载地址 J2EE 部分: 1.Switch能否用string做参数? 在 Jav...
    侯蛋蛋_阅读 2,424评论 1 4
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,698评论 0 9
  • 2017年2月9日 晴 在提交了辞职申请后,我成功的变成了一个无业游民。 说来也是好笑,在一家婚姻咨询的公司里,...
    一只林小瑶阅读 448评论 0 0
  • 原文地址 一个很美但是旨在解决一个不存在的需求的产品一定会失败,一个很丑但是解决了一个真实问题的产品将会成功。 “...
    Shouseooo阅读 926评论 2 11