zoukankan      html  css  js  c++  java
  • Othello UVA

    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;
    }
  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/worldcreator-zh/p/10556040.html
Copyright © 2011-2022 走看看