Xiangqi UVA - 1589
https://vjudge.net/problem/UVA-1589
刘汝佳的第四章习题,思路没有难点,是用来练习函数化和自定而下的编程方法的。
首先分析输入输出,思考用什么容器存储数据,处理问题时会用到什么,然后写出大体框架。
可以简单的先写成接收输入,处理问题,按标准要求输出,然后把输入输出部分完善(因为本题这部分比较简单)
然后写处理部分,要判断当前情况下将死等于判断下一步所有能走的位置是不是都为死棋。(有一种特殊情况,直接可以飞将吃对方的帅来取胜?!!!)
再细化问题,把判断该位置是不是死棋分为判断该位置是不是能被红方的棋子的某一个棋子吃到。
然后再分别写出每一种棋子的判断方式。
帅:从该位置到它同一列的下方搜索,如果搜索到帅以外的棋子,则该位置被挡住了,不能被帅将死。否则被将死。
车:和帅差不多,只不过要分别搜索从该位置开始上下左右的路线。
炮:和车差不多,都是搜从该位置开始上下左右的路线,不过搜到一个棋子时计数器cnt++;并判定当前棋子是不是炮,若是炮且cnt==2;则该位置被将死。
马:也是以该位置为中心,用马的行动模式来搜索周围的八个点(是马可以跳的那八个点),如果找到了马还要再加一步判定是否蹩马腿。具体方法见代码。
思路就是以将的位置为起点,带入不同棋子的行动模式,因为如果我按照你那么走能到你那,咱俩棋子相同,你肯定也能反过来到这里。
#include<iostream> #include<string> #include<vector> #define mms(a,b) memset(a,b,sizeof(a)) #define rep(i,n,t) for(int i=(n);i<(t);i++) #define per(i,n,t) for(int i=(n);i>(t);i--) #define N 11 #define M 10 using namespace std; char chessboard[N][M]; bool cheakmeat = true; bool cheak(int x, int y) { if (x < N && x >= 1 && y < M && y >= 1) return true; return false; } bool cheakjiang(int x, int y) { if (x <= 3 && x >= 1 && y <= 6 && y >= 4) return true; return false; } bool judgeG(int x, int y)//判帅 { rep(i, x+1, N) { if (chessboard[i][y] == 0) {} else if (chessboard[i][y] == 'G') return true; else return false; } return false; } bool judgeH(int x, int y)//判马 { int temp[8][8]{ {1,-2},{-1,-2},{2,-1},{-2,-1},{-2,1},{2,1},{-1,2},{1,2} }; rep(i, 0, 8) { int xx = x + temp[i][0]; int yy = y + temp[i][1]; if (cheak(xx, yy)) { if (chessboard[xx][yy] == 0) {} else if (chessboard[xx][yy] == 'H') { int x2 = (temp[i][0] * -1) / 2, y2 = (temp[i][1] * -1) / 2; if (chessboard[xx + x2][yy + y2] == 0) return true; return false; } } } return false; } bool judgeR(int x, int y)//判车 { per(i, x-1, 0) { if (chessboard[i][y] == 0) {} else if (chessboard[i][y] == 'R') return true; else break; } rep(i, x+1, N) { if (chessboard[i][y] == 0) {} else if (chessboard[i][y] == 'R') return true; else break; } per(j, y-1, 0) { if (chessboard[x][j] == 0) {} else if (chessboard[x][j] == 'R'&&j != y) return true; else break; }rep(j, y+1, M) { if (chessboard[x][j] == 0) {} else if (chessboard[x][j] == 'R'&&j != y) return true; else return false; } return false; } bool judgeC(int x, int y)//判炮 { int cnt = 0; per(i, x-1, 0) { if (chessboard[i][y] == 0) {} else { cnt++; if (chessboard[i][y] == 'C') { if(cnt == 2) return true; } } } cnt = 0; rep(i, x+1, N) { if (chessboard[i][y] == 0) {} else { cnt++; if (chessboard[i][y] == 'C') { if (cnt == 2) return true; } } } cnt = 0; per(j, y-1, 0) { if (chessboard[x][j] == 0) {} else { cnt++; if (chessboard[x][j] == 'C') { if (cnt == 2) return true; } } } cnt = 0; rep(j, y+1, M) { if (chessboard[x][j] == 0) {} else { cnt++; if (chessboard[x][j] == 'C') { if (cnt == 2) return true; } } } return false; } void judge(int x, int y) { int temp[4][4]{ {0,-1},{0,1},{-1,0},{1,0} }; if (judgeG(x,y)) { cheakmeat = false; return; } rep(i, 0, 4) { if (cheakjiang(x + temp[i][0], y + temp[i][1])) { if (judgeG(x + temp[i][0], y + temp[i][1])) continue; else if (judgeH(x + temp[i][0], y + temp[i][1])) continue; else if (judgeR(x + temp[i][0], y + temp[i][1])) continue; else if (judgeC(x + temp[i][0], y + temp[i][1])) continue; cheakmeat = false; break; } } } vector<string> V; int main() { int x, y, n; while (cin >> n >> x >> y) { if (!n && !x && !y) break; else { //初始化 cheakmeat = true; mms(chessboard, 0); //输入 rep(i, 0, n) { int a, b; char size; cin >> size >> a >> b; chessboard[a][b] = size; } //判断 judge(x, y); //输出 if (cheakmeat) V.push_back("YES"); else V.push_back("NO"); } } rep(i, 0, V.size()) { cout <<V[i]<< endl; } return 0; }
写的时候要细心,不然会有好多条件判断的细小错误,只能一遍遍用数据测试出来。ac代码没有优化,肯定还可以写的更精简。