标签:memset 注意 target 编程 push clu 存在 处理 个数
https://vjudge.net/problem/UVA-220
和之前的xiangqi差不多,都是棋盘类的,在二维数组里做各种情况的判断。也是锻炼自定而下的编程方法。
题目中说要实现三个功能:
①:确定所有可以走的位置坐标,并以坐标形式输出。
②:要可以进行落子并且对按规则进行被前后夹死的对手棋子反转。
③:退出时要可以输出棋盘。
(要注意这三件事是可以以任意顺序做的,不要理解为M之前必须先L,我就是这样wa了好久orz)
做①时我用的是遍历棋盘,对于当前自己的棋子进行判断,若自己棋子周身八个格子存在对手棋子,则在此方向进行进一步搜索,直到找到空坐标。(当然要判断一下出界)
③更简单,输出数组就好,每次输出一整个数组后要再多换一行(整个题目的最后一次不用)
②我做的时候不想再用遍历,所以就直接读取了①中存储的每个坐标,但是知道坐标是不够的,还要知道每个坐标吃子的方向才行,我只能想到用
vector<pair<int,int>,pair<int,int>>这种容器来存储,两组一对数,一组存坐标,另一组存方位。
最后因为是多组输入,所以一定要注意初始化!!!;
#include<iostream> #include<string> #include<vector> #include<algorithm> #include<map> #include<set> #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 mms(a,b) memset(a,b,sizeof(a)) #define N 9 using namespace std; int chessboard[N][N]; vector<pair<pair<int, int>, pair<int, int>>> Posi; int cntb = 0, cntw = 0; bool comp(pair<pair<int, int>, pair<int, int>> a, pair<pair<int, int>, pair<int, int>> b)//升序排列 { if (a.first.first == b.first.first) return a.first.second < b.first.second; return a.first.first < b.first.first; } bool cheak(int x, int y)//检查坐标是否出界 { return (x > 0 && y > 0 && x < N&&y < N); } void print_board()//打印整个棋盘 { rep(i, 1, N) { rep(j, 1, N) { if (chessboard[i][j] == 0)cout << ‘W‘; else if (chessboard[i][j] == 1)cout << ‘B‘; else cout << ‘-‘; } cout << endl; } } bool search(int player) { rep(i, 1, N) rep(j, 1, N)//对于棋盘上每一个点 { if (chessboard[i][j] == 1) cntb++; if (chessboard[i][j] == 0) cntw++;//数黑白子个数 if (chessboard[i][j] == player)rep(x, -1, 2) rep(y, -1, 2)//搜索周身每格 { if (x || y) { int xx = i + x; int yy = j + y; int flag=0; while (cheak(xx, yy) && (chessboard[xx][yy] == !player))//如果该坐标合法且上边的棋子为对手的。 { xx+=x; yy+=y;//继续按该方向搜索 flag++; } if (flag>0) if (cheak(xx, yy)&&chessboard[xx][yy] == -1) Posi.push_back(make_pair(make_pair(xx, yy), make_pair(x, y)));//如果停止的原因是因为该坐标上无棋子,加入解答容器。 } } } return Posi.size();//以Posi种有无答案作为返回值 } void change(int player, int x, int y) { chessboard[x][y] = player; if (player) cntb++;else cntw++; rep(i, 0, Posi.size()) { if (make_pair(x, y) == Posi[i].first)//先找路线,再找方向 { int xx, yy, a, b; a = (-1)*Posi[i].second.first; b = (-1)*Posi[i].second.second; xx = x + a; yy = y + b; while (cheak(xx, yy)&&chessboard[xx][yy]!=player) { chessboard[xx][yy] = player; if (player) { cntb++; cntw--; } else { cntb--; cntw++; } xx += a; yy += b; } } } } int main() { int n; cin >> n; rep(i, 0, n)//n次游戏 { //初始化期盼和状态 mms(chessboard, -1); Posi.clear(); cntb = cntw = 0; rep(x, 1, N) rep(y, 1, N) { char chess; cin >> chess; if (chess == ‘W‘) chessboard[x][y] = 0; else if (chess == ‘B‘) chessboard[x][y] = 1; } int player = 1; char c; cin >> c; if (c == ‘W‘) player = 0; //处理输入 string S; while (cin >> S) { cntw = cntb = 0; Posi.clear();int have_posi = search(player); if (S == "Q") { print_board(); if (i != n - 1) cout << endl; break; } else if (S == "L") { if (have_posi) { sort(Posi.begin(), Posi.end(), comp); set<pair<int, int>> Output; vector<pair<pair<int, int>,pair<int,int>>>::iterator it = Posi.begin(); while (it != Posi.end()){Output.insert(it->first);it++;} set<pair<int, int>>::iterator sit = Output.begin(); while (sit != Output.end()) { if (sit != Output.begin()) cout << " (" << sit->first << "," << sit->second << ")"; else cout << "(" << sit->first << "," << sit->second << ")"; sit++; } } else { cout << "No legal move."; player = !player; }//若无位置可走,转换玩家 cout << endl; } else { change(player, S[1] - 48, S[2] - 48); if (cntb < 10)cout << "Black - "; else cout << "Black - "; cout << cntb; if (cntw < 10) cout << " White - "; else cout << " White - "; cout << cntw << endl; player = !player;//每次一名玩家走完,交换玩家并初始化Posi; } } } return 0; }
标签:memset 注意 target 编程 push clu 存在 处理 个数
原文地址:https://www.cnblogs.com/worldcreator-zh/p/10556040.html