美文网首页
象棋 UVa1589

象棋 UVa1589

作者: 尹傲雄 | 来源:发表于2017-05-24 14:26 被阅读218次

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

   思路导图
下面贴一下代码,更详细的解释在代码的注释里,代码有点冗长,有能力的可以把相同的地方写成函数(比如说帅和车的判断是可以放一起的)
#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;

    }


}

相关文章

  • 象棋 UVa1589

    看到这个题目基本的想法是,将黑将能走的四个方向都遍历一遍,然后再判断判断红方能否吃掉它。如果所有可能的走向都会被将...

  • CH3-UVA1589

    UVA1589 这题是题模拟题, 模拟题最重要的是考虑清楚细节.我一开始的思路没有错.但是读入数据的时候出错了,调...

  • 有种思念叫做象棋

    有种思念叫做象棋。 象棋最初是老爸教的。我自从碰了象棋,我就成了象棋迷,不过最开始引导我喜爱象棋的理由是当时的动画...

  • 如何绕过社群运营的五个坑

    车马炮社群里卖象棋 为什么说车马炮社群里卖象棋是一个坑?车马炮社群就是象棋社群,象棋本身就是社群用户的标配,对象棋...

  • 姨妈是女同胞中唯一会下象棋的。

    象棋小王子 从小姨妈教会了我下象棋,从此我从象棋中找到人生的乐趣。 没有手机的年代,我只会下象棋。 象棋和读书是我...

  • 人生是一步棋

    文/洛夕璇 最近又恋上了下象棋,好像有十年没有下象棋了,有人说,下象棋在于棋技,我觉得象棋的...

  • 出门三件事

    每天出门三件事,下象棋,下象棋,下象棋。不要抑制自己的棋瘾,输了再来!

  • 象棋是什么?

    象棋是什么? 象棋就是—— 你永远都无法下赢你的父亲 还有你的部分小伙伴 象棋是什么? 象棋就是—— 你快要输时的...

  • 象棋

    风起云涌天地暗,楚河汉界两军战。 马鸣萧萧闯敌阵,炮越大河声震天。 士相运筹保将帅,车卒拼杀血未寒。 ...

  • 象棋

    今天我和妈妈一起去少年宫唱歌了,在回来的路上我给妈妈说,我要把中国象棋和围棋都要传承下去。

网友评论

      本文标题:象棋 UVa1589

      本文链接:https://www.haomeiwen.com/subject/hbfoxxtx.html