zoukankan      html  css  js  c++  java
  • 算法习题---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;
    }
  • 相关阅读:
    FZU 2150 Fire Game
    POJ 3414 Pots
    POJ 3087 Shuffle'm Up
    POJ 3126 Prime Path
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    字符数组
    HDU 1238 Substing
    欧几里德和扩展欧几里德详解 以及例题CodeForces 7C
    Codeforces 591B Rebranding
  • 原文地址:https://www.cnblogs.com/ssyfj/p/11137729.html
Copyright © 2011-2022 走看看