河南萌新联赛2026第(一)场:河南工业大学A题题解
侧边栏壁纸
  • 累计撰写 4 篇文章
  • 累计收到 2 条评论

河南萌新联赛2026第(一)场:河南工业大学A题题解

llwqs
2026-07-27 / 2 评论 / 5 阅读 / 正在检测是否收录...

这道题是一道经典的模拟题,考察的是对复杂规则的理解和代码实现能力。 题目地址

题目解析

这道题要求我们模拟一个在环形棋盘上进行的多玩家大富翁游戏。我们需要根据给定的规则,一步步执行每个玩家的回合,直到游戏结束。 非常非常大的令人恶心的模拟

核心规则梳理

游戏环境:

一个有 m 个格子的环形棋盘,编号 1 到 m。第 m 格的下一格是第 1 格。
n 名玩家,初始都在第 1 格,拥有各自的初始金币。

回合流程:

玩家按编号 1 到 n 的顺序循环行动。
停牌状态: 如果玩家处于停牌状态(由监狱格导致),则解除停牌,本回合不移动、不使用骰子。
正常移动: 否则,使用下一个骰子点数 d,顺时针移动 d 格。
触发效果: 移动后,根据落点格子的类型触发相应效果。
格子类型与效果:
起点格 (第 1 格): 落在该格获得 200 金币。注意:游戏开始时在第 1 格不触发此效果。
地产格:
无主: 如果玩家金币足够,必须购买(扣除价格,玩家成为地主)。
有主 (且地主不是自己): 需要向地主支付过路费。如果金币不足,支付所有金币并破产。
自己所有: 无效果。
幸运格: 获得 150 金币。
惩罚格: 扣除 100 金币。如果金币不足,扣除所有金币并破产。
监狱格: 进入停牌状态(下一回合不行动)。

破产规则:

当需要支付金币(过路费或惩罚)时,如果当前金币不足以支付,则支付所有剩余金币,金币变为 0,并立即破产。
如果金币恰好足够,支付后金币变为 0,但不会破产。
玩家破产后:金币为 0,其所有地产变为无主,并永久退出游戏(不再参与后续回合)。

游戏结束条件:

场上仅剩 1 名玩家未破产。
所有骰子都已使用完毕。

输出:

游戏结束时,按玩家编号顺序输出所有玩家的最终状态(金币数量)。

解题思路

这是一个纯粹的模拟问题,关键在于准确地将题目规则转化为代码逻辑。

数据结构设计:

玩家 (Player): 需要一个结构体来存储每个玩家的状态,包括:当前金币、当前位置、是否破产、是否停牌、拥有的地产列表。
棋盘 (Board): 需要一个数组或向量来表示棋盘上的每个格子。每个格子需要存储其类型和相关信息(如地产的价格、过路费、地主ID)。
骰子 (D): 一个数组或向量,按顺序存储所有骰子点数。

模拟主循环:

使用一个循环来模拟游戏回合。
在循环内部,遍历所有玩家(从 1 到 n)。
对于每个玩家,首先检查其是否已破产,如果破产则跳过。
然后检查游戏是否应该结束(只剩一个玩家或骰子用完)。
如果玩家未破产且游戏未结束,则执行该玩家的回合:
处理停牌状态。
如果未停牌,则掷骰子、移动、触发落点效果。
在处理效果时,需要仔细处理金币的增减和破产判断。

完整代码

#include<bits/stdc++.h>
using namespace std;

enum celltype{
    start,
    grounds,
    lucky,
    punish,
    jali,
};

struct ground{
    long long price;
    long long toll;
    int owner_id;
    ground(long long p, long long t) : price(p), toll(t), owner_id(-1) {}
};

struct cell{
    celltype type;
    ground* str;
    cell() : type(start), str(NULL) {} 
    cell(celltype t) : type(t), str(NULL) {}
    cell(ground* p) : type(grounds), str(p) {}
};

struct Player{
    int id;
    long long coins;
    int pos;
    bool is_broke;
    bool is_ban;
    vector<int> groundd;
    Player(int i, long long c) : id(i), coins(c), pos(1), is_broke(false), is_ban(false) {}
};

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    int n, m;
    cin >> n >> m;
    
    vector<Player> players;
    for(int i = 1; i <= n; i++){
        long long ci;
        cin >> ci;
        players.emplace_back(i, ci);
    }
    
    vector<cell> board(m + 1);
    for(int i = 1; i <= m; i++){
        int types;
        cin >> types;
        if(types == 0){
            board[i] = cell(start);
        } else if(types == 1){
            long long p, t;
            cin >> p >> t;
            board[i] = cell(new ground(p, t));
        } else if(types == 2){
            board[i] = cell(lucky);
        } else if(types == 3){
            board[i] = cell(punish);
        } else if(types == 4){
            board[i] = cell(jali);
        }
    }
    
    int k;
    cin >> k;
    vector<long long> d(k);
    for(int i = 0; i < k; i++){
        cin >> d[i];
    }
    
    int d_i = 0;
    int player_nobroke = n;
    
    while(d_i < k && player_nobroke > 1){
        for(int i = 0; i < n; i++){
            Player& player = players[i];
            if(player.is_broke) continue;
            if(d_i >= k || player_nobroke <= 1) break;
            
            if(player.is_ban){
                player.is_ban = false;
            } else {
                long long ds = d[d_i++];
                long long new_pos = (long long)player.pos + ds;
                player.pos = (int)((new_pos - 1) % m + 1);
                
                cell& current_cell = board[player.pos];
                switch(current_cell.type){
                case start:
                    player.coins += 200;
                    break;
                case grounds: {
                        ground* str = current_cell.str;
                        if(str->owner_id == -1){
                            if(player.coins >= str->price){
                                player.coins -= str->price;
                                str->owner_id = player.id;
                                player.groundd.push_back(player.pos);
                            }
                        }
                        else if(str->owner_id != player.id){
                            long long t = str->toll;
                            if(player.coins < t){
                                players[str->owner_id - 1].coins += player.coins;
                                player.coins = 0;
                                player.is_broke = true;
                                player_nobroke--;
                                for(int str_pos : player.groundd){
                                    board[str_pos].str->owner_id = -1;
                                }
                                player.groundd.clear();
                            } else {
                                player.coins -= t;
                                players[str->owner_id - 1].coins += t;
                            }
                        }
                        break;
                    }
                    
                case lucky:
                    player.coins += 150;
                    break;
                    
                case punish:
                    if(player.coins < 100){
                        player.coins = 0;
                        player.is_broke = true;
                        player_nobroke--;
                        for(int str_pos : player.groundd){
                            board[str_pos].str->owner_id = -1;
                        }
                        player.groundd.clear();
                    } else {
                        player.coins -= 100;
                    }
                    break;
                    
                case jali:
                    player.is_ban = true;
                    break;
                }
                
                if(d_i >= k || player_nobroke <= 1) break;
            }
        }
    }
    
    for (int i = 0; i < n; ++i) {
        if (players[i].is_broke) {
            cout << "bankrupt 0";
        } else {
            cout << players[i].coins << " " << players[i].groundd.size();
        }
        if (i < n - 1) cout << "\n";
    }
    cout << endl;
    
    for (int i = 1; i <= m; ++i) {
        if (board[i].type == grounds){
            delete board[i].str;
        }
    }
    return 0;
}
1

评论 (2)

取消
  1. 头像
    bblb
    Android · Google Chrome

    牛逼

    回复
    1. 头像
      llwqs 作者
      Windows 10 · Google Chrome
      @ bblb

      谢谢

      回复