ゆずりさ
1594 字
8 分钟
2024-2025 ICPC NERC, Kyrgyzstan Qualification Contest
题目链接
A. Problem Statement
题意
给 行字符串,问输入了几个回车
题解
输出
代码
void idol_produce(int testCase) {
/*Code Here*/
int n;
cin >> n;
cout << n - 1 << '\n';
}
B. Ant Hill
题意
给定 个数表示蚂蚁山中,蚂蚁的进出,蚂蚁山在任何时刻蚂蚁的数量都不为负数,求最开始至少有几只蚂蚁
题解
从头开始模拟蚂蚁的进出,设 为当前蚂蚁山的数量,
代码
void idol_produce(int testCase) {
/*Code Here*/
int n;
cin >> n;
ll ans = 0;
ll p = 0;
for(int i = 1;i <= n; i++){
ll x;
cin >> x;
p += x;
if(p <= 0) ans = max(ans, -p);
}
cout << ans << '\n';
}
C. Linear Maze
题意
个房间,每次可以从房间 转移到房间 ,有 个特殊房间,如果在奇数次访问这样一个房间,下一步则会传送到房间 ,问离开迷宫要经过几个房间
题解
当访问到普通房间时,步数 + 1,如果访问到特殊房间,则步数 + 1后翻倍,显然访问到特殊房间后,回到该房间需要重新走相同的路程
代码
void idol_produce(int testCase) {
/*Code Here*/
int n, k;
cin >> n >> k;
vector<int> a(n + 1);
for(int i = 1;i <= k; i ++){
int x;
cin >> x;
a[x] = 1;
}
ll ans = 0;
for(int i = 1;i <= n; i++){
ans ++;
if(a[i]) ans *= 2;
}
cout << ans << '\n';
}
D. Grouping
题意
将 个数字分为最小数目的好数集,好数集的定义如下:
集合的大小不超过
集合的最大值和最小值之差不超过
题解
排序原数组,贪心地将其放入当前集合中,若满足则放入,否则另开一个新集合
代码
void idol_produce(int testCase) {
/*Code Here*/
int n, m, k;
cin >> n >> m >> k;
vector<ll> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
sort(a.begin(), a.end());
ll num = -INF;
int cnt = m;
int ans = 0;
for (int i = 0; i < n; i++) {
if (cnt == k) {
cnt = 1;
num = a[i];
ans++;
} else if (a[i] - num > m) {
cnt = 1;
num = a[i];
ans++;
} else {
cnt++;
}
}
cout << ans << endl;
}
H. Hierarchy
题意
给定几个公司的员工架构树,求员工数量最多的一个公司
题解
DFS求每个树的大小即可
代码
void idol_produce(int testCase) {
/*Code Here*/
int n;
cin >> n;
vector<vector<int> > son(n + 1);
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
son[x].push_back(i);
}
vector<int> dp(n + 1, 0);
int ans = 0;
int maxn = 0;
function<void(int)> dfs = [&](int u) {
if (son[u].empty()) {
dp[u] = 1;
return;
}
for (auto v : son[u]) {
dfs(v);
dp[u] += dp[v];
if (u == 0 && dp[v] > maxn) {
maxn = dp[v];
ans = v;
}
}
dp[u] += 1;
};
dfs(0);
cout << ans << ' ' << maxn << endl;
}
I. Study Day
题意
参加 次讲座,每次可以获得 点知识点,可以在参加前进行冥想使得这次获得的知识点翻倍,不能连续冥想两次,问知识点最多为多少?
题解
令 表示第 次未冥想获得的最多知识点, 表示第 次冥想获得的最多的知识点,那么满足:
代码
void idol_produce(int testCase) {
/*Code Here*/
int n;
cin >> n;
vector<vector<ll> > dp(2, vector<ll>(n + 1));
vector<string> ans(2);
for (int i = 1; i <= n; i++) {
ll x;
cin >> x;
auto tmp = ans;
if (dp[0][i - 1] > dp[1][i - 1]) {
dp[0][i] = dp[0][i - 1] + x;
ans[0] = tmp[0] + 'O';
} else {
dp[0][i] = dp[1][i - 1] + x;
ans[0] = tmp[1] + 'O';
}
dp[1][i] = dp[0][i - 1] + 2 * x;
ans[1] = tmp[0] + 'M';
}
if (dp[0][n] > dp[1][n]) {
cout << dp[0][n] << endl;
cout << ans[0] << endl;
} else {
cout << dp[1][n] << endl;
cout << ans[1] << endl;
}
}
F. Traffic Lights
题意
有 个路口,到达一个路口花费 ,路口处红灯亮 秒,绿灯亮 秒,一开始红灯亮了 秒,求通过所有路口花费的总时间
题解
令 为到达路口时花费的总时间,那么该路口的灯已经亮了 秒,显然路口的灯以 为周期循环,令 ,当 时,为绿灯,直接通过,当 时为红灯,
代码
void idol_produce(int testCase) {
/*Code Here*/
int n;
cin >> n;
vector<int> a(n + 1), r(n + 1), g(n + 1), d(n + 1);
for(int i = 1; i <= n; i++){
cin >> a[i];
}
for(int i = 1; i <= n; i++){
cin >> r[i] >> g[i] >> d[i];
}
ll time = 0;
for(int i = 1;i <= n; i++){
time += a[i];
ll t = time + d[i];
ll rem = t % (r[i] + g[i]);
if(rem < g[i]){
continue;
}
else{
time += r[i] + g[i] - rem;
}
}
cout << time << endl;
}
G. Need More Gold
题意
有 个怪物,每个怪物打败需要 个金币(不花费),打败后获得 个金币,求积累 个金币最少打败怪物的数量和顺序
题解
维护优先队列,每一次选择当前可打败的价值最高的怪物。
代码
struct node {
int id;
ll x, y;
bool operator<(const node &rhs) const { return x < rhs.x; }
};
void idol_produce(int testCase) {
/*Code Here*/
ll w, n;
cin >> w >> n;
vector<node> a(n + 1);
for (int i = 0; i < n; i++) {
cin >> a[i].x >> a[i].y;
a[i].id = i + 1;
}
sort(a.begin(), a.end(), [](node a, node b) { return a.y > b.y; });
priority_queue<node> q;
vector<int> ans;
ll now = 0;
while (!a.empty() && a.back().y == 0) {
q.push(a.back());
a.pop_back();
}
while (!q.empty() && now < w) {
node t = q.top();
q.pop();
now += t.x;
ans.emplace_back(t.id);
while (!a.empty() && a.back().y <= now) {
q.push(a.back());
a.pop_back();
}
}
if (now < w) {
cout << -1 << endl;
return;
}
cout << ans.size() << endl;
for (auto i : ans) {
cout << i << " ";
}
}
E. Mountain Ranges
题意
座山,假如相邻两座山之间的高度差不大于 ,则视为同一座山脉,问最小的 使得恰好划分为 座山脉
题解
二分 ,当 时, 向上二分,否则向上二分
代码
void idol_produce(int testCase) {
/*Code Here*/
int n, m;
cin >> n >> m;
vector<int> a(n + 1);
for(int i = 1;i <= n; i++){
cin >> a[i];
}
if(n == 1){
cout << 1 << '\n';
return;
}
int l = 1, r = 1e6;
int ans = -1;
while(l <= r){
int mid = (l + r) >> 1;
int cnt = 1;
for(int i = 2;i <= n; i++){
if(abs(a[i] - a[i - 1]) > mid){
cnt++;
}
}
if(cnt > m){
l = mid + 1;
}
else if(cnt == m){
ans = mid;
r = mid - 1;
}
else{
r = mid - 1;
}
}
cout << ans << endl;
}
2024-2025 ICPC NERC, Kyrgyzstan Qualification Contest
https://fuyuki.fun/posts/题解/2024-kyrgyzstan-qualification-contest/