• 算法习题---4-1象棋(UVa1589)


    一:题目

    在黑方只有一个“将”的情况下,红方只有(车、马、炮)(可以多个)、帅的情况下,判断黑方是否被将死

    (一)题目详解

    其中棋盘按照坐标方式表示,左上角为(1,1),列数最大9,行数最大10
    G  表示  将帅
    R  表示  车
    H  表示  马
    C  表示  炮

    (二)样例输入

    2 1 4  //第一行第一个数字:表示红方有2个棋子  第二三个表示黑方“将”位置在(1,4)
    G 10 5  //表示红方“帅”在(10,5) 
    R 6 4  //表示红方“车”在(6,4)
      空行表示一次输入结束
    3 1 5  //第一行第一个数字:表示红方有3个棋子 第二三个表示黑方“将”位置在(1,5)
    H 4 5  //表示红方“马”在(4,5)
    G 10 5  //表示红方“帅”在(10,5)
    C 7 5  //表示红方“炮”在(7,5)
    
    0 0 0  //全0表示结束

    二:代码实现

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define N 7
    int Num;    //用于保存获取的个数
    int xq[N][3];    //棋盘数据

    进行棋盘、坐标数据获取

    int getData(int* r,int* c)
    {
        int n;
        int i=0;
    
        //进行数据获取
        while (1)
        {
            //获取数据起始位置
            scanf("%d %d %d", &n, r, c);    //n在(2,7)之间
            Num = n;
            if (n == 0)
                return -1;    //全部结束
    
            //获取数据,填充棋盘
            while (n--)
            {
                getchar();
                scanf("%c %d %d", (char*)&xq[i][0], &xq[i][1], &xq[i][2]);
                i++;
            }
            return 1;    //本次输入结束
        }
    }

    判断中间是否有棋子,返回棋子个数

    int judgeCaseInMid(int r1,int c1, int r2, int c2)
    {
        int j,min,max,count=0;
        min = max = 0;
    
        if (r1 == r2)    //判断行上是否同行中间有棋子
        {
            c1 > c2 ? min = c2, max = c1 : min = c1, max = c2;
            for (j = 0; j < Num; j++)
                if (xq[j][1] == r1 && (xq[j][2]>min&&xq[j][2] < max))
                    count++;    //有中间棋子
        }
        if (c1 == c2)    //判断列上是否同列中间有棋子
        {
            r1 > r2 ? min = r2, max = r1 : min = r1, max = r2;
            for (j = 0; j < Num; j++)
                if (xq[j][2] == c1 && (xq[j][1]>min&&xq[j][1] < max))
                    count++;    //有中间棋子
        }
    
        return count;    //返回棋子个数
    }

    单独将马拿出来处理:因为马特殊

    //判断马是否将死黑方    (r1,c1)为马,(r2,c2)为敌将
    bool judgeCaseForHorse(int r1, int c1, int r2, int c2)
    {
        //利用勾股定理
        int a, b;
        a = r1 - r2;
        b = c1 - c2;
    
        if (a*a + b*b == 5)
        {
            //考虑别马腿
            if ((r1 - r2) == 2)
            {
                for (int i = 0; i < Num; i++)
                    if (xq[i][1] == r1 - 1 && xq[i][2] == c1)
                        return false;
            }
    
            if ((r1 - r2) == -2)
            {
                for (int i = 0; i < Num; i++)
                    if (xq[i][1] == r1 + 1 && xq[i][2] == c1)
                        return false;
            }
    
            if ((c1 - c2) == 2)
            {
                for (int i = 0; i < Num; i++)
                    if (xq[i][1] == c1 - 1 && xq[i][2] == r1)
                        return false;
            }
    
            if ((c1 - c2) == -2)
            {
                for (int i = 0; i < Num; i++)
                    if (xq[i][1] == c1 + 1 && xq[i][2] == r1)
                        return false;
            }
    
            return true;
        }
    
        return false;
    }

    判断黑方将下一步是否可以走

    //G是将 R是车 C是炮 H是马
    int judgeCKByNextByte(int r, int c)
    {
        int i;
        //遍历棋盘红方数据,判断是否将死这一步
        for (i = 0; i < Num;i++)
        {
            switch (xq[i][0])
            {
            case 'G':    //判断将
                //判断黑方是否在同一列
                if (xq[i][2] == c)
                    if (!judgeCaseInMid(r, c, xq[i][1], xq[i][2]))
                        return 1;    //将死
                break;
            case 'R':    //判断车
                //车可以横向纵向走
                //先判断是否在同一行或者同一列
                if (xq[i][1] == r || xq[i][2] == c)    //同行/列
                    //判断是否中间有棋子
                    if (!judgeCaseInMid(r, c, xq[i][1], xq[i][2]))
                        return 1;    //将死
                break;
            case 'C':    //判断炮
                if (xq[i][1] == r || xq[i][2] == c)    //同行/列
                    //判断是否中间有棋子
                    if (1==judgeCaseInMid(r, c, xq[i][1], xq[i][2]))
                        return 1;    //将死
                break;
            case 'H':    //判断马
                if (judgeCaseForHorse(xq[i][1], xq[i][2], r, c))
                    return 1;
                break;
            }
        }
        return 0;
    }

    判断是否将死黑方

    bool judgeCK(int r, int c)
    {
        //判断将的运行空间(1,4)->(1,6) 
        //                  (2,4)->(2,6)
        //                (3,4)->(3,6)
    
        if (r >= 1 && r < 3)//向下走
            if (judgeCKByNextByte(r+1, c) == 0)
                return false;    //未将死
        
        if (r > 1 && r <= 3)//向上走
            if (judgeCKByNextByte(r - 1, c) == 0)
                return false;    //未将死
    
        if (c >= 4 && c < 6)//向右走
            if (judgeCKByNextByte(r, c + 1) == 0)
                return false;    //未将死
    
        if (c > 4 && c <= 6)//向左走
            if (judgeCKByNextByte(r, c - 1) == 0)
                return false;    //未将死
    
        if ((r == 1 && c == 4) || (r == 2 && c == 5))//右下走
            if (judgeCKByNextByte(r + 1, c + 1) == 0)
                return false;    //未将死
    
        if ((r == 3 && c == 6) || (r == 2 && c == 5))//左上走
            if (judgeCKByNextByte(r - 1, c - 1) == 0)
                return false;    //未将死
    
        if ((r == 1 && c == 6) || (r == 2 && c == 5))//左下走
            if (judgeCKByNextByte(r + 1, c - 1) == 0)
                return false;    //未将死
    
        if ((r == 3 && c == 4) || (r == 2 && c == 5))//右上走
            if (judgeCKByNextByte(r - 1, c + 1) == 0)
                return false;    //未将死
    
        return true;    //将死
    }

    主函数

    int main()
    {
        int row, col;
    
        freopen("data.in", "r", stdin);
        freopen("data.out", "w", stdout);
    
        while (1)
        {
            //进行数据输入
            if (getData(&row, &col) == -1)
                return 0;
            //进行数据处理,判断是否将死
            if (judgeCK(row, col))
                printf("YES
    ");
            else
                printf("NO
    ");
        }
    
        freopen("CON", "r", stdin);
        freopen("CON", "w", stdout);
    
        return 0;
    }
  • 相关阅读:
    网络监控之三:ifstat、iftop
    JavaScript框架比较
    Enterprise Architect
    设计模式:Abstract Factory和Builder(转)
    Flexibility Pattern架构和设计模式
    Struts的html:errors的用法
    更好的浏览器判定
    纯CSS细线伪表格
    javascript 随机数
    一些javascript题目
  • 原文地址:https://www.cnblogs.com/ssyfj/p/11137729.html
Copyright © 2020-2023  润新知