Xiangqi UVA - 1589

https://vjudge.net/problem/UVA-1589

刘汝佳的第四章习题,思路没有难点,是用来练习函数化和自定而下的编程方法的。

首先分析输入输出,思考用什么容器存储数据,处理问题时会用到什么,然后写出大体框架。

可以简单的先写成接收输入,处理问题,按标准要求输出,然后把输入输出部分完善(因为本题这部分比较简单)

然后写处理部分,要判断当前情况下将死等于判断下一步所有能走的位置是不是都为死棋。(有一种特殊情况,直接可以飞将吃对方的帅来取胜?!!!)

再细化问题,把判断该位置是不是死棋分为判断该位置是不是能被红方的棋子的某一个棋子吃到。

然后再分别写出每一种棋子的判断方式。

帅:从该位置到它同一列的下方搜索,如果搜索到帅以外的棋子,则该位置被挡住了,不能被帅将死。否则被将死。

车:和帅差不多,只不过要分别搜索从该位置开始上下左右的路线。

炮:和车差不多,都是搜从该位置开始上下左右的路线,不过搜到一个棋子时计数器cnt++;并判定当前棋子是不是炮,若是炮且cnt==2;则该位置被将死。

马:也是以该位置为中心,用马的行动模式来搜索周围的八个点(是马可以跳的那八个点),如果找到了马还要再加一步判定是否蹩马腿。具体方法见代码。

思路就是以将的位置为起点,带入不同棋子的行动模式,因为如果我按照你那么走能到你那,咱俩棋子相同,你肯定也能反过来到这里。

#include<iostream>
#include<string>
#include<vector>
#define mms(a,b) memset(a,b,sizeof(a))
#define rep(i,n,t) for(int i=(n);i<(t);i++)
#define per(i,n,t) for(int i=(n);i>(t);i--)
#define N 11
#define M 10
using namespace std;
char chessboard[N][M]; bool cheakmeat = true;

bool cheak(int x, int y)
{
    if (x < N && x >= 1 && y < M && y >= 1) return true;
    return false;
}
bool cheakjiang(int x, int y)
{
    if (x <= 3 && x >= 1 && y <= 6 && y >= 4) return true;
    return false;
}
bool judgeG(int x, int y)//判帅
{
    rep(i, x+1, N)
    {
        if (chessboard[i][y] == 0) {}
        else if (chessboard[i][y] == ‘G‘) return true;
        else  return false;
    }
    return false;
}
bool judgeH(int x, int y)//判马
{
    int temp[8][8]{ {1,-2},{-1,-2},{2,-1},{-2,-1},{-2,1},{2,1},{-1,2},{1,2} };
    rep(i, 0, 8)
    {
        int xx = x + temp[i][0]; int yy = y + temp[i][1];
        if (cheak(xx, yy))
        {
            if (chessboard[xx][yy] == 0) {}
            else if (chessboard[xx][yy] == ‘H‘) {
                int x2 = (temp[i][0] * -1) / 2, y2 = (temp[i][1] * -1) / 2;
                if (chessboard[xx + x2][yy + y2] == 0) return true;
                return false;
            }
        }
    }
    return false;
}
bool judgeR(int x, int y)//判车
{
    per(i, x-1, 0)
    {
        if (chessboard[i][y] == 0) {}
        else if (chessboard[i][y] == ‘R‘) return true;
        else break;
    }
    rep(i, x+1, N)
    {
        if (chessboard[i][y] == 0) {}
        else if (chessboard[i][y] == ‘R‘) return true;
        else break;
    }
    per(j, y-1, 0)
    {
        if (chessboard[x][j] == 0) {}
        else if (chessboard[x][j] == ‘R‘&&j != y) return true;
        else break;
    }rep(j, y+1, M)
    {
        if (chessboard[x][j] == 0) {}
        else if (chessboard[x][j] == ‘R‘&&j != y) return true;
        else return false;
    }
    return false;
}
bool judgeC(int x, int y)//判炮
{
    int cnt = 0;
    per(i, x-1, 0)
    {
        if (chessboard[i][y] == 0) {}
        else
        {
            cnt++; if (chessboard[i][y] == ‘C‘) { if(cnt == 2) return true; }
        }
    }
    cnt = 0;
    rep(i, x+1, N)
    {
        if (chessboard[i][y] == 0) {}
        else
        {
            cnt++; if (chessboard[i][y] == ‘C‘) { if (cnt == 2) return true; }
        }
    }
    cnt = 0;
    per(j, y-1, 0)
    {
        if (chessboard[x][j] == 0) {}
        else
        {
            cnt++; if (chessboard[x][j] == ‘C‘) { if (cnt == 2) return true; }
        }
    }
    cnt = 0;
    rep(j, y+1, M)
    {
        if (chessboard[x][j] == 0) {}
        else
        {
            cnt++; if (chessboard[x][j] == ‘C‘) { if (cnt == 2) return true; }
        }
    }
    return false;
}
void judge(int x, int y)
{
    int temp[4][4]{ {0,-1},{0,1},{-1,0},{1,0} };
    if (judgeG(x,y)) { cheakmeat = false; return; }
    rep(i, 0, 4)
    {
        if (cheakjiang(x + temp[i][0], y + temp[i][1]))
        {
            if (judgeG(x + temp[i][0], y + temp[i][1])) continue;
            else if (judgeH(x + temp[i][0], y + temp[i][1])) continue;
            else if (judgeR(x + temp[i][0], y + temp[i][1])) continue;
            else if (judgeC(x + temp[i][0], y + temp[i][1])) continue;
            cheakmeat = false; break;
        }
    }
}

        vector<string> V;
int main()
{
    int x, y, n;
    while (cin >> n >> x >> y)
    {
        if (!n && !x && !y) break;
        else
        {
            //初始化
            cheakmeat = true; mms(chessboard, 0);
            //输入
            rep(i, 0, n)
            {
                int a, b; char size;
                cin >> size >> a >> b;
                chessboard[a][b] = size;
            }
            //判断
            judge(x, y);
            //输出

            if (cheakmeat) V.push_back("YES");
            else V.push_back("NO");

        }
    }
    rep(i, 0, V.size())
            {
                cout <<V[i]<< endl;
            }
    return 0;
}

写的时候要细心,不然会有好多条件判断的细小错误,只能一遍遍用数据测试出来。ac代码没有优化,肯定还可以写的更精简。

原文地址:https://www.cnblogs.com/worldcreator-zh/p/10544861.html

时间: 2024-08-28 01:28:50

Xiangqi UVA - 1589的相关文章

UVA 1589 Xiangqi

Z1589 - Xiangqi Time limit: 3.000 seconds 做这题的时候WA了很多次. 解决思路是,枚举黑方将军可以移动的位置,接着判断这些位置是否被红方将军,如果所有位置会被红方吃掉,那么就是checkmate了. 要注意的情况可能就是双炮将军. 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 char board[12][12]; 6 int dr[4] = { 1,

UVA - 1589 Xiangqi (模拟)

Xiangqi Problem Description Xiangqi is one of the most popular two-player board games in China. The game represents a battle between two armies with the goal of capturing the enemy's "general" piece. In this problem, you are given a situation of

UVa 1589 Xiangqi(模拟 HDU4121)

题意  给你一个黑方被将军的象棋残局  判断红方是否已经把黑方将死 模拟题  注意细节就行了  看黑方的将是否四个方向都不能走 #include<cstdio> #include<cstring> using namespace std; const int N = 12; char brd[N][N]; int dx[] = { -1, 1, 0, 0}, dy[] = {0, 0, -1, 1}; int hx[] = { -2, -1, -2, -1, 1, 2, 1, 2}

UVA 1589:Xiangqi (模拟 Grade D)

题目: 象棋,黑棋只有将,红棋有帅车马炮.问是否死将. 思路: 对方将四个方向走一步,看看会不会被吃. 代码: 很难看……WA了很多发,还越界等等. #include <cstdio> #include <cstring> #include <cstdlib> char graph[13][13]; int go[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; bool inBlackPalace(int x, int y) { return

UVA 1589 Xiangqi(仔细的模拟)

题意:中国象棋大家都玩过,就是基本规则,只有将,帅,车,马,炮. 解题思路: 思路是把各个棋子能攻击到的位置在judge数组相应的位置上标记出来 首先考虑马蹩马腿的情况,这个比较好考虑,注意不要越界就行了. 车,不能穿过自己方的车,马,炮,帅.但范围可以穿过'将',因为'将'下一步会移动. 炮,不可以用'将'作为炮架,其余都可以,因为'将'下一步会移动. 帅,情况很简单.一条线. 要注意的是,每个棋子的攻击范围,是必须到另一个棋子的位置的 考虑数据 3 1 5 R 1 1 R 2 5 G10 5

UVA 1589 象棋

题意: 给出一个黑方的将, 然后 红方有 2 ~ 7 个棋子, 给出摆放位置,问是否已经把黑将将死, 红方已经将军. 分析: 分情况处理, 车 马 炮, 红将情况跟车是一样的. 建一个数组board保存棋局, 然后建一个数组moveable用来算出黑将当前位置能走的格子(1可走, 0不可走, 一开始都是1), 判断一下黑将上下左右四个方位是否能走, 而且走了之后算一下当前位置moveable是否0即可. 代码: 1 #include <bits/stdc++.h> 2 using namesp

uva 1589 by sixleaves

坑爹的模拟题目.自己对于这种比较复杂点得模拟题的能力概述还不够,还多加练习.贴别是做得时候一直再想如何检查车中间有没有棋子,炮中间有没有棋子.到网上参考别人的代码才发先这么简单的办法,自己尽然想不到.多加练习,总结下该题目吧.   1 #include <stdio.h>  2 #include <string.h>  3 #define N 12  4   5 char brd[N][N];  6 int dx[] = {1,-1,0,0}, dy[] = {0,0,1,-1};

【UVA】1589 Xiangqi(挖坑待填)

题目 题目 ? ? 分析 无力了,noip考完心力憔悴,想随便切道题却码了250line,而且还是错的,知道自己哪里错了,但特殊情况判起来太烦了,唯一选择是重构,我却没有这勇气. 有空再写吧,最近真的快疯了. ? ? 代码 对拍 #include <bits/stdc++.h> int main() { for(int i=1;i<=100;i++){ system("rand.exe > in.txt"); system("1589.exe <

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d