ABC457-最大堆/贪心+构造

1045 字
5 分钟
ABC457-最大堆/贪心+构造

ABC459#

Tokio Marine & Nichido Fire Insurance Programming Contest 2026 (AtCoder Beginner Contest 459) - AtCoder

E有关树的遍历,还没学过;F和G都太难,,,等我再深造深造

Easy:A、B

Mid:C、D

Hard:E

Very-Hard:F、G

B-模拟

简单模拟即可

模拟
n = int(input())
ss = input().strip().split()
m = {
'a': '2', 'b': '2', 'c': '2',
'd': '3', 'e': '3', 'f': '3',
'g': '4', 'h': '4', 'i': '4',
'j': '5', 'k': '5', 'l': '5',
'm': '6', 'n': '6', 'o': '6',
'p': '7', 'q': '7', 'r': '7', 's': '7',
't': '8', 'u': '8', 'v': '8',
'w': '9', 'x': '9', 'y': '9', 'z': '9'
}
ans = ''.join(m[s[0]] for s in ss)
print(ans)
C-模拟

题意:

n个从左到右排列成一行的格子,初始时所有格子都没有放置方块

q个查询,每个查询有两个子段p,x

p为1,在从左数第x个格子中放置1个方块;之后,如果每个格子都至少有一个方块,则从每个格子中移除一个方块

p为2,输出至少用于x个方块的格子数量

题解:

显然的,直接减去1的操作会超时

所有格子同时减去1可以等价为把判断标准往上提高1

为此定义c[v]为当前计数值恰好等于v的格子的数量;mn为记录当前所有格子都至少拥有的“基础层数”

在1操作中,首先执行a[x]++c[a[x]]++,如果c[a[x]] == n,意味着所有格子的计数都≥a[x],并且是因为a[x]刚增加后才到达,因此目前所有格子的最小值为a[x];将mn记录为当前最小值a[x]

在2操作中,由于我们并没有进行删除操作,所以在这一步中,我们需要得到的实际方块数位x+mn

模拟
MAX = 3 * 10 ** 5
a = [0] * (MAX + 1)
c = [0] * (MAX + 1)
n, q = map(int, input().split())
mn = 0
for _ in range(q):
t, x = map(int, input().split())
if t == 1:
# 操作1:在格子 x 加一个方块
a[x] += 1
c[a[x]] += 1
# 如果某个高度 v 的格子数达到了 n,说明每个格子至少有 v 块
if c[a[x]] == n:
mn = a[x]
else:
# 查询:至少 y 块 = 至少 y+mn 块
need = x + mn
if need > MAX:
print(0)
else:
print(c[need])
D-最大堆/贪心+构造

题意:

给定一个字符串s

判断是否可以通过重新排列使得任意两个相邻字符都不相同

题解:

首先如果某个字符出现次数超过一半,那么无法进行构造

其次,在构造序列时,贪心的选择剩余次数最多、且不等于上一个字符的字符

贪心+构造
for _ in range(int(input())):
s = input()
n = len(s)
cnt = [0] * 26
for c in s:
cnt[ord(c) - ord("a")] += 1
if max(cnt) > (n + 1) // 2:
print("No")
continue
ans = []
prev = -1
while True:
val = 0
idx = -1
for i in range(26):
if i == prev:
continue
if val < cnt[i]:
idx = i
val = cnt[i]
if idx == -1:
break
ans.append(chr(ord('a') + idx))
cnt[idx] -= 1
prev = idx
print("Yes")
print("".join(ans))

值得一提的是,本体还可以通过最大堆进行构造

最大堆
import heapq
from collections import Counter
for _ in range(int(input())):
s = input().strip()
n = len(s)
freq = Counter(s)
if max(freq.values()) > (n + 1) // 2:
print("No")
continue
heap = [(-cnt, ch) for ch, cnt in freq.items()]
heapq.heapify(heap)
res = []
prev = None
while heap:
cnt1, ch1 = heapq.heappop(heap)
if ch1 == prev:
if not heap:
break
cnt2, ch2 = heapq.heappop(heap)
res.append(ch2)
prev = ch2
if -cnt2 > 1:
heapq.heappush(heap, (cnt2 + 1, ch2))
heapq.heappush(heap, (cnt1, ch1))
else:
res.append(ch1)
prev = ch1
if -cnt1 > 1:
heapq.heappush(heap, (cnt1 + 1, ch1))
print("Yes")
print(''.join(res))
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CHAR 26
typedef struct {
char ch;
int cnt;
} Node;
int cmp(const void* a, const void* b) {
Node* nodeA = (Node*)a;
Node* nodeB = (Node*)b;
return nodeB->cnt - nodeA->cnt;
}
char* reorganizeString(char* s) {
int n = strlen(s);
int freq[26] = {0};
for (int i = 0; i < n; i++) {
freq[s[i] - 'a']++;
}
int maxFreq = 0;
for (int i = 0; i < 26; i++) {
if (freq[i] > maxFreq) {
maxFreq = freq[i];
}
}
if (maxFreq > (n + 1) / 2) {
return "";
}
char* res = (char*)malloc((n + 1) * sizeof(char));
res[n] = '\0';
int resIdx = 0;
char prev = '\0';
while (1) {
int bestIdx = -1;
int bestCnt = 0;
for (int i = 0; i < 26; i++) {
if (freq[i] > 0 && (char)(i + 'a') != prev) {
if (freq[i] > bestCnt) {
bestCnt = freq[i];
bestIdx = i;
}
}
}
if (bestIdx == -1) {
break;
}
char ch = (char)(bestIdx + 'a');
res[resIdx++] = ch;
freq[bestIdx]--;
prev = ch;
}
if (resIdx != n) {
free(res);
return "";
}
return res;
}
ABC457-最大堆/贪心+构造
http://blog.7a7a68.xyz/posts/abc459/
作者
Waning
发布于
2026-05-25
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Waning
愿你明日如绚丽之花.
公告
还活着.
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
56
分类
8
标签
20
总字数
125,693
运行时长
0
最后活动
0 天前

目录