• UVA-1589 象棋(模拟)


    题目:(传送门)

    给出一个象棋的残局,下一步是黑棋走,判断黑棋是不是被将死。

    思路:

    读完这个题,知道是一个模拟题,然后想到用两个二维数组来模拟棋盘,一个(mp数组)用来存残局,一个(res数组)用来处理红棋在棋盘上产生的对黑棋的限制。

    将红棋的马、车、炮、将写成函数来分别处理。这样处理完之后,判断一下黑棋的四周是不是有可以走的格子,有的话不是将死,没有的是就是被将死了。

    1、可以将车和将写成一个函数来处理,这里可以标记与棋子处于同一行和同一列中的格子,如下图:

    红色圈出来的部分不能走,注意马上边的格子是可以走的,而如果和车一行的只有对方的将,那么这一行都不能走。

    2、对马的处理,如下图:

     

    同理,红色的部分不能走,注意马有蹩腿的情况出现如上右图

     3、对炮棋的处理最为复杂,具体情况如图:

     

    如上右图中绿色的部分是可以走的,左图中的红色部分是不可以走的。

    代码:(略长)

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define MAX 1e9;
    #define FRE() freopen("in.txt","r",stdin)
    #define FRO() freopen("out.txt","w",stdout)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const int maxn = 200000;//G-general-1  R-chariot-2 C-cannon-3 H-horse-4 Black-5
    map<char,int> key;
    int mp[11][10],res[11][10];
    int N,bx,by;
    struct T{
        char ch;
        int x,y;
    }t[10];
    
    
    
    bool isIn(int x,int y) {//判断是不是在棋盘的范围内
        if(x>=1 && x<=10 && y>=1 && y<=9) {
            return true;
        }
        return false;
    }
    
    void makeGR(int x,int y) {//处理车和将的关系
        if(isIn(x,y)) {
            for(int i=x-1; i>=1; i--) { //Up
                res[i][y] = -1;
                if(mp[i][y]!=0 && mp[i][y]!='B') {//从当前位置起到另外的第一个棋子(不包括黑棋)中间的位置都是不可以走的
                    break;
                }
            }
            for(int i = x+1; i<=3; i++) { //Down
                res[i][y] = -1;
                if(mp[i][y]!=0 && mp[i][y]!='B') {
                    break;
                }
            }
            for(int i = y-1; i>=1; i--) { //Left
                res[x][i] = -1;
                if(mp[x][i]!=0 && mp[x][i]!='B') {
                    break;
                }
            }
            for(int i = y+1; i<=9; i++) { //Right
                res[x][i] = -1;
                if(mp[x][i]!=0 && mp[x][i]!='B') {
                    break;
                }
            }
        }
    }
    
    void makeH(int x,int y) {//处理马棋
        if(isIn(x-2,y-1) && mp[x-1][y]==0) { //Up//排除蹩腿的情况一共八个方向
            res[x-2][y-1] = -1;
        }
        if(isIn(x-2,y+1) && mp[x-1][y]==0){
            res[x-2][y+1] = -1;
        }
        if(isIn(x+2,y-1) &&  mp[x+1][y]==0) { //Down
            res[x+2][y-1] = -1;
        }
        if(isIn(x+2,y+1) &&  mp[x+1][y]==0){
            res[x+2][y+1] = -1;
        }
        if(isIn(x-1,y-2) && mp[x][y-1]==0){//Left
            res[x-1][y-2] = -1;
        }
        if(isIn(x+1,y-2) && mp[x][y-1]==0){
            res[x+1][y-2] = -1;
        }
        if(isIn(x-1,y+2) && mp[x][y+1]==0) { //Right
            res[x-1][y+2] = -1;
        }
        if(isIn(x+1,y+2) && mp[x][y+1]==0){
            res[x+1][y+2] = -1;
        }
    }
    
    
    void makeC(int x,int y) {//处理炮棋
        if(x==1&&(y>=4&&y<=6)) {
            if(mp[2][y]!=0 && mp[2][y]!='B'){
                res[3][y] = -1;
            }
        }
        int tx=0,ty=0;
        for(int i = x-1; i>=1; i--) { //Up
            if(isIn(i,y) && mp[i][y]!=0 && mp[i][y]!='B') {//寻找与炮棋一行的棋子的位置(不包括黑棋)
                tx = i,ty = y; //cout<<"GG"<<endl;
                break;
            }
            if(isIn(i,y) && mp[i][y]=='B')
                return;
        }
        //<<"TX: "<<tx<<"   TY: "<<ty<<endl;
        for(int i = tx-1; i>=1; i--) { //Up标记从找到的棋子到棋盘边缘的格子
           // if(isIn(i,y) && (mp[i][y]==0 || mp[i][y]=='B')) {
                res[i][y]=-1;
            //}
            if(isIn(i,y) && mp[i][y]!=0 && mp[i][y]!='B'){//出现第二个格子就停止
                break;
            }
        }
        for(int i=y-1; i>=1; i--) { //Left
            if(isIn(x,i) && mp[x][i]!=0 && mp[x][i]!='B') {
                tx=x, ty = i;
                break;
            }
            if(isIn(x,i) && mp[x][i]=='B'){
                return;
            }
        }
        for(int i=ty-1; i>=1; i--) { //Left
            //if(isIn(x,i) && (mp[x][i]==0 || mp[x][i]=='B')) {
                res[x][i] = -1;
            //}
            if(isIn(x,i) && mp[x][i]==0 && mp[x][i]!='B'){
                break;
            }
        }
        for(int i = y+1; i<=9; i++) {//Right
            if(isIn(x,i) && mp[x][i]!=0 && mp[x][i]!='B') {
                tx = x,ty=i;
                break;
            }
            if(isIn(x,i) && mp[x][i]=='B'){
                return;
            }
        }
        for(int i = y+1; i<=9; i++){//Right
            //if(isIn(x,i) && (mp[x][i]==0 || mp[x][i]=='B')){
                res[x][i] = -1;
            //}
            if(isIn(x,i) && mp[x][i]==0 && mp[x][i]!='B'){
                break;
            }
        }
    }
    
    bool in(int x,int y){//判断黑棋是不是在规定的格子内部
        if(x>=1 && x<=3 && y>=4 && y<=6){
            return true;
        }
        return false;
    }
    
    bool judge(int x,int y){//判断有没有被将死
        bool ok = false;
        if(in(x-1,y) && res[x-1][y]!=-1) ok = true;
        if(in(x+1,y) && res[x+1][y]!=-1) ok = true;
        if(in(x,y-1) && res[x][y-1]!=-1) ok = true;
        if(in(x,y+1) && res[x][y+1]!=-1) ok = true;
        return ok;
    }
    
     void check1(){
        for(int i = 1; i<=10; i++){
            for(int j = 1; j<=9; j++){
                printf("%2d ",res[i][j]);
            }
            printf("
    ");
        }
     }
    
      void check2(){
        for(int i = 1; i<=10; i++){
            for(int j = 1; j<=9; j++){
                printf("%2d ",mp[i][j]);
            }
            printf("
    ");
        }
     }
    
    
    int main() {
        //FRE();scanf("%d%d%d",&N,&bx,&by)
        //FRO();
        while(cin>>N>>bx>>by) {//必须要吐槽一下,这里的输出太懵逼了,用scanf就出错,用cin就AC......
            //printf("bx:%d  by:%d
    ",bx,by);
            memset(mp,0,sizeof(mp));
            memset(res,0,sizeof(res));
            if(N==0&&bx==0&&by==0) {
                break;
            }
            mp[bx][by] = 'B';
            char ch;
            int rx,ry;
    
            for(int i = 0; i<N; i++) {
                getchar();
                cin>>ch>>rx>>ry;
                //scanf("%c %d %d",&ch,&rx,&ry);
                //printf("ch:%c rx:%d ry:%d
    ",ch,rx,ry);
                mp[rx][ry] = ch;
                t[i] = T{ch,rx,ry};
            }
    
            for(int i = 0; i<N; i++){
                ch = t[i].ch;
                rx = t[i].x;
                ry = t[i].y;
                if(ch=='R' || ch=='G') {
                    makeGR(rx,ry);
                }
                else if(ch=='H') {
                    makeH(rx,ry);
                }
                else if(ch=='C') {
                    makeC(rx,ry);
                }
            }
    //        check2();
    //        cout<<endl<<endl;
    //        check1();
            if(judge(bx,by)){
                printf("NO
    ");
            }else{
                printf("YES
    ");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    P2572 [SCOI2010]序列操作
    python学习笔记2
    嗯,python
    ETROBOT——审题
    条件编译
    第三章单片机简介
    模拟输入输出
    arduino库函数1
    arduino相关文献阅读
    Arduino的小灯亮起来~~~
  • 原文地址:https://www.cnblogs.com/sykline/p/10269154.html
Copyright © 2020-2023  润新知