hdu 4121 xiangqi 模拟

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4121

康复训练

小模拟

几个坑:

1.黑general可以通过飞过来吃掉红general来摆脱困境

2.可能需要注意某些棋子被黑general吃掉的情况

本质是搜索 这种题完全不可能卡时间

将、车、炮用一种判法

马另用一种判法

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;

int xx, yy;//敌军将帅原始位置
int rcnt, ccnt, hcnt, gcnt;
int r[10][2];
int c[10][2];
int h[10][2];
int g[10][2];
int board[12][11];
int hboard[12][11];

const int walk[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
const int hwalk[8][2] = {2, 1, 1, 2, -1, 2, -2, 1, -1, -2, -2, -1, 1, -2, 2, -1};
const int hcheck[4][2] = {1, 1, -1, 1, -1, -1, 1, -1};

int lineCheck(int a, int b, int mode, int k)
{
    int cnt = 0;

    if(a > b)
        swap(a, b);

    for(int i = a+1; i < b; i++)
    {
        if(mode == 0)
        {
            if(board[k][i] == 1)
                cnt++;
        }
        else if(mode == 1)
        {
            if(board[i][k] == 1)
                cnt++;
        }
    }
    return cnt;
}

bool check(int x, int y)
{
    for(int i = 0; i < gcnt; i++)
    {
        if(g[i][1] == y)
        {
            if(lineCheck(x, g[i][0], 1, y) == 0)
                return true;
        }
    }

    for(int i = 0; i < rcnt; i++)
    {
        if(r[i][0] == x && !(r[i][0] == x && r[i][1] == y))
        {
            if(lineCheck(r[i][1], y, 0, x) == 0)
                return true;
        }

        else if(r[i][1] == y && !(r[i][0] == x && r[i][1] == y))
        {
            if(lineCheck(r[i][0], x, 1, y) == 0)
                return true;
        }
    }

    for(int i = 0; i < ccnt; i++)
    {
        if(c[i][0] == x && !(c[i][0] == x && c[i][1] == y))
        {
            if(lineCheck(c[i][1], y, 0, x) == 1)
                return true;
        }
        else if(c[i][1] == y && !(c[i][0] == x && c[i][1] == y))
        {
            if(lineCheck(c[i][0], x, 1, y) == 1)
                return true;
        }
    }

    for(int i = 0; i < 8; i++)
    {
        int a = x + hwalk[i][0];
        int b = y + hwalk[i][1];
        if(1 <= a && a <= 10 && 1 <= b && b <= 9)
        {
            if(hboard[a][b] == 1)
            {
                int aa = x + hcheck[i/2][0];
                int bb = y + hcheck[i/2][1];
                if(board[aa][bb] == 0)//判绊马脚
                    return true;
            }
        }

    }

    return false;
}

int main()
{
    //freopen("in.txt", "r", stdin);

    int n;
    char buf[10];
    while(scanf("%d%d%d", &n, &xx, &yy) == 3 && n != 0)
    {
        memset(board, 0, sizeof(board));
        memset(hboard, 0, sizeof(hboard));
        rcnt = 0; ccnt = 0; hcnt = 0; gcnt = 0;

        int tmpx, tmpy;
        for(int i = 0; i < n; i++)
        {
            scanf("%s%d%d", buf, &tmpx, &tmpy);
            board[tmpx][tmpy] = 1;

            if(buf[0] == 'G')
            {
                g[gcnt][0] = tmpx;
                g[gcnt][1] = tmpy;
                gcnt++;
            }
            else if(buf[0] == 'R')
            {
                r[rcnt][0] = tmpx;
                r[rcnt][1] = tmpy;
                rcnt++;
            }
            else if(buf[0] == 'C')
            {
                c[ccnt][0] = tmpx;
                c[ccnt][1] = tmpy;
                ccnt++;
            }
            else if(buf[0] == 'H')
            {
                hboard[tmpx][tmpy] = 1;
                h[hcnt][0] = tmpx;
                h[hcnt][1] = tmpy;
                hcnt++;
            }
        }

        bool flag = true;

        if(yy == g[0][1])
        {
            if(lineCheck(xx, g[0][0], 1, yy) == 0)
            {
                printf("NO
");
                continue;
            }
        }

        for(int i = 0; i < 4; i++)
        {
            int x = xx + walk[i][0];
            int y = yy + walk[i][1];
            if(1 <= x && x <= 3 && 4 <= y && y <= 6)
            {
                flag = check(x, y);
            }

            if(!flag)
                break;
        }

        if(flag)
            printf("YES
");
        else
            printf("NO
");

    }

    return 0;
}

一开始写得急 边写边想

然后就搞得里面有很多代码块有重复 但却懒得去重构 心想过了就好

然后改来改去还是wa

最后试着把重复的代码块抽出来写了一个lineCheck函数就过了

模拟题还是不能懒

特别要注意如果有重复的代码块最好另起一个函数

一是只需要写一次 出错的机会小了

二是如果发现错了 也好改 就改一处 不会有什么改漏了改串了的情况

原文地址:https://www.cnblogs.com/dishu/p/4259631.html