UVA-1589 象棋(模拟)
Posted sykline
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于UVA-1589 象棋(模拟)的主要内容,如果未能解决你的问题,请参考以下文章