Autochess 寒假训练赛 set

这篇博客主要介绍了如何实现自走棋中棋子升级的过程,通过使用哈希映射、队列和集合来管理棋子状态。算法核心在于判断场上棋子数量,当满足合成条件时进行升星操作。博客还提及了代码中需要注意的细节,如空位处理和避免额外的空格问题。
摘要由CSDN通过智能技术生成

Link
模拟,set

题意

看了半天发现就是模拟自走棋升级棋子过程,还蛮有趣的。
m , n , k m, n, k m,n,k 分别代表加入棋子次数,位置个数,合成一个更高星的所需的个数。
具体要求: 设当前加入的棋子名称为 s s s。(每次加入的均为1星形态)

  1. if 若场上已有3星 s s s ,直接跳过。
  2. else if,如果场上已有 k − 1 k-1 k1个1星 s s s,则移除这些棋子,并在最左边的空位放一个2星 s s s。如果此时有 k − 1 k-1 k1 个2星 s s s,则以同样规则合成3星。
  3. else 如果场上有空位,则将它放到最左侧的空位。

求最终每个位置放的棋子名称,若空着则输出 -1

思路

map<string, int> mp 把字符串映射到数字,用一个set<int> c 维护当前空着的位置。用queue<int> q[i]维护 i i i 号字符串当前在场上的数量。
每次插入 i i i 字符串时,若可以合成则清空queue[i]并将元素全部加入 c ,否则弹出 c 首元素并加入queue[i]。满、空的情况单独特判一下就好。

只要场上有k-1个同样的,就可以合成,不一定需要空位。
卡行末空格,差评。

int m, n, k;
unordered_map<string, int> mp;
// map<string, int> mp;
string loc[maxn];
queue<int> q[maxn];
set<int> c;
int t = 0;
void solve() {
    string s;
    c.clear();
    int cnt = 0;
    int now, top;
    cin >> m >> n >> k;
    mp.clear();
    for(int i = 0; i <= n; i++) {
        loc[i].erase();
    }
    for(int i = 1; i <= n; i++)
        c.insert(i);
    for(int i = 1; i <= m; i++)
     {
         cin >> s;
         string s0 = s + '3';
         if(mp[s0]) {
             continue;
         }
         if(c.empty()) {
             if(!mp[s]) mp[s] = ++cnt;
                now = mp[s];
             if(q[now].size() < k-1)
                 continue;
             while(!q[now].empty()) {
                c.insert(q[now].front());
                loc[q[now].front()] = "-1";
                q[now].pop();
             }
         }
         else {
         if(!mp[s]) mp[s] = ++cnt;
         now = mp[s];
         top = *c.begin();
         q[now].push(top);
         loc[top] = s;
         c.erase(c.begin());
         if(q[now].size() < k) continue;
         if(q[now].size() == k) {
             while(!q[now].empty()) {
                 c.insert(q[now].front());
                 loc[q[now].front()] = "-1";
                 q[now].pop();
             }
         }
         }
        string s1 = s + '2';
        if(!mp[s1]) mp[s1] = ++cnt;
        now = mp[s1];
         top = *c.begin();
         q[now].push(top);
         c.erase(c.begin());
         loc[top] = s1;
         if(q[now].size() < k) continue;
         if(q[now].size() == k) {
             while(!q[now].empty()) {
                 c.insert(q[now].front());
                 loc[q[now].front()] = "-1";
                 q[now].pop();
             }
         }
         string s2 = s + '3';
        if(!mp[s2]) mp[s2] = ++cnt;
        now = mp[s2];
         top = *c.begin();
         q[now].push(top);
         c.erase(top);
         loc[top] = s2;
     }
    for(int i = 1; i <= cnt; i++) {
        while(!q[i].empty())
            q[i].pop();
    }
     cout << "Case " << ++t << ": ";
     for(int i = 1; i < n; i++) {
         if(loc[i].size() == 0)
         cout << -1 << ' ';
         else
         cout << loc[i] << ' ';
     }
    if(loc[n].size() == 0)
        cout << -1 << endl;
    else
        cout << loc[n] << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值