zoukankan      html  css  js  c++  java
  • UVa 1589

    这个题,三个月前写了一次,当时写道200行的时候,就感觉恶心了,当时感觉再写100行也完不成。

    今天拿出这题来重写了,尽量精简代码,结果没想到90行就AC了。精简代码的好处之一便是方便调试,因为细节太多了,把很多相似的内容放在函数中就好了。

    看似四个棋子的走法不同,实则有一个共同点:都需要判断棋子和“将”所在的行或者列中,两个棋子之间的棋子数。对于“帅”和“车”,之间的棋子数必须为0。对于炮,之间的棋子数必须为1。对于马,可以利用这一点判断是否有憋马脚的情况。

    其他需要注意的点:

    1.初始棋盘中,如果将帅正对,那么红方必败。

    2.红方棋子有可能被将吃掉,需要处理。

    #include <bits/stdc++.h>
    using namespace std;
    
    struct One{
        int r, c;
        char type;
    };
    One Red[10];
    int N, r0, c0, G_NO;
    char tab[12][12];
    const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    const int Hdir[8][4] = {
        {-1, 2, 0, 2}, {1, 2, 0, 2},
        {-2, -1, -2, 0}, {-2, 1, -2, 0},
        {-1, -2, 0, -2}, {1, -2, 0, -2},
        {2, -1, 2, 0}, {2, 1, 2, 0}
    };
    inline bool in_black_palace(const int r, const int c){
        return r >= 1 && r <= 3 && c >= 4 && c <= 6;
    }
    int get_range_block(int r1, int c1, int r2, int c2){
        int cnt = 0;
        if(r1 != r2 && c1 != c2) return -1;
        if(r1 == r2){
            if(c1 > c2) swap(c1, c2);
            for(int i = c1 + 1; i <= c2 - 1; ++i)
                if(tab[r1][i] != '')
                    cnt++;
        }
        else if(c1 == c2){
            if(r1 > r2) swap(r1, r2);
            for(int i = r1 + 1; i <= r2 - 1; ++i)
                if(tab[i][c1] != '')
                    cnt++;
        }
        return cnt;
    }
    bool G(const int r, const int c, const int x, const int y){
        if(c != y) return false;
        return get_range_block(r, c, x, y) == 0;
    }
    bool R(const int r, const int c, const int x, const int y){
        int res = get_range_block(r, c, x, y);
        if(res == -1) return false;
        return res == 0;
    }
    bool H(const int r, const int c, const int x, const int y){
        for(int i = 0; i < 8; ++i){
            int x1 = x + Hdir[i][0], y1 = y + Hdir[i][1];
            if(x1 == r && y1 == c && get_range_block(x, y, x + Hdir[i][2], y + Hdir[i][3])==0)
                return true;
        }
        return false;
    }
    bool C(const int r, const int c, const int x, const int y){
        int res = get_range_block(r, c, x, y);
        if(res == -1) return false;
        return res == 1;
    }
    bool check_red_win(const int r, const int c){
        for(int i = 0; i < N; ++i) if(!(Red[i].r==r && Red[i].c==c)){
            One & t = Red[i];
            if(t.type == 'G' && G(r, c, t.r, t.c)) return true;
            if(t.type == 'R' && R(r, c, t.r, t.c)) return true;
            if(t.type == 'H' && H(r, c, t.r, t.c)) return true;
            if(t.type == 'C' && C(r, c, t.r, t.c)) return true;
        }
        return false;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        while(memset(Red, 0, sizeof(Red)), memset(tab, 0, sizeof(tab)), cin >> N >> r0 >> c0, !(N==0 && r0==0 && c0==0)){
            for(int i = 0; i < N; i++){
                One t; cin >> t.type >> t.r >> t.c;
                if(t.type=='G') G_NO = i;
                tab[t.r][t.c] = t.type; Red[i] = t;
            }
            if(G(r0, c0, Red[G_NO].r, Red[G_NO].r)) {puts("NO"); continue;}
            bool red_win = true;
            for(int i = 0; i < 4; ++i){
                int r1 = r0 + dir[i][0], c1 = c0 + dir[i][1];
                if(in_black_palace(r1, c1) && !check_red_win(r1, c1)) {red_win = false; break;}
            }
            if(red_win) puts("YES");
            else puts("NO");
        }
        return 0;
    }


  • 相关阅读:
    11.查询截取分析_慢查询日志
    10.查询截取分析_查询优化
    8.索引优化
    7.使用EXPLAIN 来分析SQL和表结构_2
    7.使用EXPLAIN 来分析SQL和表结构_1
    6.B+Tree 检索原理
    5.索引简介
    创建集合搜索帮助
    介绍SAP预留函数创建搜索帮助
    通过出口函数创建搜索帮助
  • 原文地址:https://www.cnblogs.com/kunsoft/p/5312735.html
Copyright © 2011-2022 走看看