题解:P12594 炽声音节旋
可以发现所有音符的时长都是
更具体的,对每一个时刻维护一个 vector 存放该时刻被按下的按键编号。对于某一个时刻的 tap,直接把该 tap 扔到相应时刻的 vector 里。对于一个
#include <bits/stdc++.h>
const int maxn = 100'000;
const int base = 96;
int T;
std::vector<int> timeLine[maxn];
int main() {
std::cin >> T;
for (auto _ : std::views::iota(0, T)) {
int n;
std::cin >> n;
for (auto &i : timeLine) i.clear();
int curT = 0;
for (auto _ : std::views::iota(0, n)) {
std::string line;
std::cin >> line;
auto split = [](const std::string &s, char ch) -> std::vector<std::string> {
std::vector<std::string> ret;
std::string cur;
for (auto i : s) {
if (i == ch) {
ret.push_back(cur);
cur.clear();
} else {
cur += i;
}
}
if (!cur.empty()) ret.push_back(cur);
return ret;
};
auto splited = split(line, ',');
int notevalue = std::stoi(splited[0].substr(1));
int noteTime = base / notevalue;
splited.erase(splited.begin());
for (auto notes : splited) {
auto note = split(notes, '/');
for (auto i : note) {
auto button = std::stoi(i);
if (i.size() == 1) {
timeLine[curT].push_back(button);
} else {
auto body = i.substr(3, int(i.size() - 2));
auto splitedHold = split(body, ':');
int x = std::stoi(splitedHold[0]), y = std::stoi(splitedHold[1]);
int holdTime = y * (base / x);
for (int t = 0; t <= holdTime; ++t) {
timeLine[curT + t].push_back(button);
}
}
}
curT += noteTime;
}
}
bool ans = true;
for (auto &i : timeLine) if (i.size() > 2) {
ans = false;
break;
} else if (i.size() == 2 && i[0] == i[1]) {
ans = false;
}
std::cout << (ans ? "Yes" : "No") << std::endl;
}
}
验题人 @NotEvenANeko 写了一份