https://vjudge.net/problem/UVA-220
和之前的 xiangqi 差不多, 都是棋盘类的, 在二维数组里做各种情况的判断. 也是锻炼自定而下的编程方法.
题目中说要实现三个功能:
1: 确定所有可以走的位置坐标, 并以坐标形式输出.
2: 要可以进行落子并且对按规则进行被前后夹死的对手棋子反转.
3: 退出时要可以输出棋盘.
(要注意这三件事是可以以任意顺序做的, 不要理解为 M 之前必须先 L, 我就是这样 wa 了好久 orz)
做1时我用的是遍历棋盘, 对于当前自己的棋子进行判断, 若自己棋子周身八个格子存在对手棋子, 则在此方向进行进一步搜索, 直到找到空坐标.(当然要判断一下出界)
3更简单, 输出数组就好, 每次输出一整个数组后要再多换一行 (整个题目的最后一次不用)
2我做的时候不想再用遍历, 所以就直接读取了1中存储的每个坐标, 但是知道坐标是不够的, 还要知道每个坐标吃子的方向才行, 我只能想到用
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;
- }
来源: http://www.bubuko.com/infodetail-2992167.html