UVA - 1589 —Xiangqi (思路&&模擬)
阿新 • • 發佈:2018-11-14
連結:
https://cn.vjudge.net/problem/UVA-1589
題意:
黑方只有一個帥,給出黑方帥的座標,紅方可能有車/炮和馬,問當前黑方是否被將死。
思路:
見程式碼
程式碼目前是錯的,但思路正確,有時間再改
#include <bits/stdc++.h> using namespace std; typedef struct L { int a,b; }; L General; L Chariot[2]; L Horse[2]; L Cannon[2]; int i1,i2,i3; int Qipan[11][10]; int n,x,y; int tempx,tempy; char type[10]; int flag; int checkGenerals(int x,int y)//判斷兩個將是否直面 { if(General.b == y)//首先縱座標必須一樣 { int Flag = 0; for(int i = x + 1; i < General.a; i++) { if(Qipan[i][y])//如果連線上有棋子,那麼就不是直面 return 0; } return 1; } return 0; } int checkChariot(int x1,int y1,int x2,int y2)//車 { //返回0 代表黑帥不會被將死 1 反之 int Flag = 0; int xj1,yj1,xj2,yj2; xj1 = x1 < x2? x1 : x2; xj2 = x1 > x2? x1 : x2; yj1 = y1 < y2? y1 : y2; yj2 = y1 > y2? y1 : y2; //如果一樣,說明這次移動,黑帥吃掉了這個車 if(x1 == x2 && y1 == y2) { return 0; } if(x1 == x2) { Flag = 0; for(int j = yj1 + 1; j < yj2 ; j++) if(Qipan[x1][j]) Flag = 1; if(flag == 0) return 1; } if(y1 == y2) { Flag = 0; for(int i = xj1 + 1; i < xj2 ; i++) if(Qipan[i][y1]) Flag = 1; if(flag == 0) return 1; } return 0; } int checkHorse(int x1,int y1,int x2,int y2)//ma { //一個馬可以八方向移動,但要判斷蹩馬腿的情況 if(x1+1==x2&&y1+2==y2) if(Qipan[x1][y1+1]==0) return 1; if(x1+1==x2&&y1-2==y2) if(Qipan[x1][y1-1]==0) return 1; if(x1-1==x2&&y1+2==y2) if(Qipan[x1][y1+1]==0) return 1; if(x1-1==x2&&y1-2==y2) if(Qipan[x1][y1-1]==0) return 1; if(x1+2==x2&&y1+1==y2) if(Qipan[x1+1][y1]==0) return 1; if(x1+2==x2&&y1-1==y2) if(Qipan[x1+1][y1]==0) return 1; if(x1-2==x2&&y1+1==y2) if(Qipan[x1-1][y1]==0) return 1; if(x1-2==x2&&y1-1==y2) if(Qipan[x1-1][y1]==0) return 1; return 0; } int checkCannon(int x1,int y1,int x2,int y2)//pao { int Flag=0; int xj1,yj1,xj2,yj2; xj1=x1<x2?x1:x2; xj2=x1>x2?x1:x2; yj1=y1<y2?y1:y2; yj2=y1>y2?y1:y2; if(x1==x2&&y1==y2) return 0;//判斷炮是否直接被吃掉 if(x1==x2) { for(int j=yj1+1;j<yj2;j++) if(Qipan[x1][j]) Flag++; if(Flag==1) return 1;//中間只有一個棋子 } if(y1==y2) { for(int i=xj1+1;i<xj2;i++) if(Qipan[i][y1]) Flag++; if(Flag==1) return 1;//中間只有一個棋子 } return 0; } int checkPoint(int x,int y)//只要黑帥有1種可能被吃,這種移動就不可行,返回0 { //黑帥被將死checkpoint就返回0 if(checkGenerals(x,y)) return 0; for(int i = 0; i < i1; i++) { if(checkChariot(Chariot[i].a,Chariot[i].b,x,y)) return 0; } for(int i = 0; i < i2; i++) { if(checkHorse(Horse[i].a,Horse[i].b,x,y)) return 0; } for(int i = 0; i < i3; i ++) { if(checkCannon(Cannon[i].a,Cannon[i].b,x,y)) return 0; } return 1;//沒有將死返回1 } int main() { while(cin>>n>>x>>y && n) { memset(Qipan,0,sizeof Qipan);//有棋子是1,無棋子是2 Qipan[x][y] = 1; flag = 0; i1 = i2 = i3 = 0; for(int i = 0; i < n; i++) { cin>>type>>tempx>>tempy; Qipan[tempx][tempy] = 1; if(type[0] = 'G')//帥 { General.a = tempx; General.b = tempy; } else if(type[0] = 'R')//車 { Chariot[i1].a = tempx; Chariot[i1++].b = tempy; } else if(type[0] = 'H')//ma { Horse[i2].a = tempx; Horse[i2++].b = tempy; } else if(type[0] = 'C')//pao { Cannon[i3].a = tempx; Cannon[i3++].b = tempy; } } //首先判斷帥與帥直接相對的情況 if(checkGenerals(x,y)) { cout<<"NO"<<endl; continue; } flag = 0; //之後對於黑帥的不同移動進行判斷,只要有一種可行,就說明沒將死。 if(x + 1 < 4)//可以下移 { Qipan[x][y] = 0; Qipan[x+1][y] = 1; if(checkPoint(x+1,y)) flag = 1; Qipan[x][y] = 1; Qipan[x+1][y] = 0; } if(flag) { cout<<"NO"<<endl; continue; } if(x-1 > 0) { Qipan[x][y] = 0; Qipan[x-1][y] = 1; if(checkPoint(x-1,y)) flag = 1; Qipan[x][y] = 1; Qipan[x-1][y] = 0; } if(flag) { cout<<"NO"<<endl; continue; } if(y+1 < 7) { Qipan[x][y] = 0; Qipan[x][y+1] = 1; if(checkPoint(x,y+1)) flag = 1; Qipan[x][y] = 1; Qipan[x][y+1] = 0; } if(flag) { cout<<"NO"<<endl; continue; } if(y-1 > 3) { Qipan[x][y] = 0; Qipan[x][y-1] = 1; if(checkPoint(x,y-1)) flag = 1; Qipan[x][y] = 1; Qipan[x][y-1] = 0; } if(flag) { cout<<"NO"<<endl; } cout<<"YES"<<endl; } return 0; }