Link
模拟,set
题意
看了半天发现就是模拟自走棋升级棋子过程,还蛮有趣的。
m
,
n
,
k
m, n, k
m,n,k 分别代表加入棋子次数,位置个数,合成一个更高星的所需的个数。
具体要求: 设当前加入的棋子名称为
s
s
s。(每次加入的均为1星形态)
- if 若场上已有3星 s s s ,直接跳过。
- else if,如果场上已有 k − 1 k-1 k−1个1星 s s s,则移除这些棋子,并在最左边的空位放一个2星 s s s。如果此时有 k − 1 k-1 k−1 个2星 s s s,则以同样规则合成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;
}