ArvinShaffer

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

本题存在吃子的陷阱,为了跳过吃子陷阱,考虑对于红子不处理它本身的坐标,留给其他子处理。解题思路为用二维数字组m1存红子坐标,m2表示红子所能管辖的点。

分别处理车、马、炮、帅的管辖范围。具体代码如下:

#include <iostream>
#include <cstring>

using namespace std;

int m1[13][13], m2[13][13], n, gx, gy;

void general(int x, int y) {
    for (int i = x - 1; i > 0; i--) {
        if (m1[i][y] != 0 && i > 3)
            break;
        if (i < 4) {
            m2[i][y]++;
            if (m1[i][y] != 0)
                break;
        }
    }
}
void chariot(int x, int y) {
    int i = 0;
    for (i = x + 1; i < 11; i++) {
        m2[i][y]++;
        if (m1[i][y] != 0)
            break;
    }

    for (i = x - 1; i > 0; i--) {
        m2[i][y]++;
        if (m1[i][y] != 0)
            break;
    }

    for (i = y + 1; i < 10; i++) {
        m2[x][i]++;
        if (m1[x][i] != 0)
            break;
    }

    for (i = y - 1; i > 0; i--) {
        m2[x][i]++;
        if (m1[x][i] != 0)
            break;
    }

}

void cannon(int x, int y) {
    int flag, i;

    flag = 0;
    for (i = x + 1; i < 11; i++) {
        if (flag) {
            m2[i][y]++;
            if (m1[i][y])
                break;
        }
        if (flag == 0 && m1[i][y] != 0)
            flag = 1;
    }

    flag = 0;
    for (i = x - 1; i > 0; i--) {
        if (flag) {
            m2[i][y]++;
            if (m1[i][y])
                break;
        }
        if (flag == 0 && m1[i][y] != 0)
            flag = 1;
    }

    flag = 0;
    for (i = y + 1; i < 10; i++) {
        if (flag) {
            m2[x][i]++;
            if (m1[x][i])
                break;
        }
        if (flag == 0 && m1[x][i] != 0)
            flag = 1;
    }

    flag = 0;
    for (i = y - 1; i > 0; i--) {
        if (flag) {
            m2[x][i]++;
            if (m1[x][i])
                break;
        }
        if (flag == 0 && m1[x][i] != 0)
            flag = 1;
    }

}

void horse(int x, int y) {
    if (x > 2 && m1[x - 1][y] == 0) {
        if (y > 1)
            m2[x - 2][y - 1]++;
        if (y < 9)
            m2[x - 2][y + 1]++;
    }
    if (x < 9 && m1[x + 1][y] == 0) {
        if (y > 1)
            m2[x + 2][y - 1]++;
        if (y < 9)
            m2[x + 2][y + 1]++;
    }
    if (y > 2 && m1[x][y - 1] == 0) {
        if (x > 1)
            m2[x - 1][y - 2]++;
        if (x < 10)
            m2[x + 1][y - 2]++;
    }
    if (y < 8 && m1[x][y + 1] == 0) {
        if (x > 1)
            m2[x - 1][y + 2]++;
        if (x < 10)
            m2[x + 1][y + 2]++;
    }
}

int judge() {
    int res = 1;
    if (gx > 1 && m2[gx - 1][gy] == 0)
        res = 0;
    if (gx < 3 && m2[gx + 1][gy] == 0)
        res = 0;
    if (gy > 4 && m2[gx][gy - 1] == 0)
        res = 0;
    if (gy < 6 && m2[gx][gy + 1] == 0)
        res = 0;
    return res;
}
int main() {
    //freopen("input1.in", "rw", stdin);
    //freopen("output1.in", "w", stdout);
    int red[10][3];
    char cmd[5];
    while (cin >> n >> gx >> gy && n) {
        memset(m1, 0, sizeof(m1));
        memset(m2, 0, sizeof(m2));
        for (int i = 0; i < n; i++) {
            cin >> cmd >> red[i][1] >> red[i][2];
            red[i][0] = cmd[0];
            m1[red[i][1]][red[i][2]] = cmd[0];
        }
        for (int i = 0; i < n; i++) {
            if (red[i][0] == 'G')
                general(red[i][1], red[i][2]);
            if (red[i][0] == 'R')
                chariot(red[i][1], red[i][2]);
            if (red[i][0] == 'C')
                cannon(red[i][1], red[i][2]);
            if (red[i][0] == 'H')
                horse(red[i][1], red[i][2]);
        }
        if (judge())
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

网上找的生成测试数据的代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;


int main()
{
    freopen("input1.in", "w", stdout);
    srand(unsigned(time(0)));
    int maxn = 6, count = 0;
    int dir[11][10];
    int keep = 1;
    const char s0[] = "RRCCHH";
    for (int s = (1<<maxn) - 1; s >= 1; s--)
        for (int num = 1000; num; num--)
        {
            printf("%d\n",keep++);
            memset(dir, 0, sizeof(dir));
            int n = 0, is = 0;
            int r0 = 1 + rand() % 3, c0 = 4 + rand() % 3;//黑棋将的位置
            dir[r0][c0] = 1;
            int r1 = 8 + rand() % 3, c1 = 4 + rand() % 3;//红棋将的位置
            while (c0 == c1)//目的是使黑红两将不在同一竖直位置
                c1 = 4 + rand() % 3;
            dir[r1][c1] = 1;
            for (int i = 0; i < maxn; i++)//n值从6至1开始变化
                if (s & (1<<i))
                    n++;
            printf("\n%d %d %d\nG %d %d\n",n + 1, r0, c0, r1, c1);//打印第一行,第二行
            count++;
            for (int i = 0; i < maxn; i++)
            if (s & (1<<i))
            {
                int r = 1 + rand() % 10, c = 1 + rand() % 9;//车马炮位置
                if (is == 0 && s0[i] != 'C')
                {
                    if (s0[i] != 'H')//
                    {
                        r = r0 + 1;
                        c = c0;
                        //printf("车%c\n",s0[i]);
                    }
                    else//
                    {
                        r = r0 + 2;
                        c = c0 + 1;
                        //printf("马%c\n",s0[i]);
                    }
                    is = 1;
            }
            else//炮车马
            {
                while (dir[r][c])
                {
                    r = 1 + rand() % 10;
                    c = 1 + rand() % 9;
                }
                //printf("炮车马%c\n",s0[i]);
            }
            dir[r][c] = 1;
            printf("%c %d %d\n", s0[i], r, c);
        }
    }
    printf("0 0 0\n");
    return 0;
}

 

posted on 2017-11-13 20:42  ArvinShaffer  阅读(202)  评论(0编辑  收藏  举报