[acwing周赛复盘] 第 86 场周赛20230114
- 一、本周周赛总结
- 二、 4794. 健身
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 三、4795. 安全区域
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 四、4796. 删除序列
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 六、参考链接
一、本周周赛总结
- 去吃羊蝎子了,回来补题。
- T1模拟
- T2模拟
- T3DP
二、 4794. 健身
链接: 4794. 健身
1. 题目描述
2. 思路分析
用模3来归类,计数。
3. 代码实现
# Problem: 健身
# Contest: AcWing
# URL: https://www.acwing.com/problem/content/4797/
# Memory Limit: 256 MB
# Time Limit: 1000 ms
import sys
import bisect
import random
import io, os
from bisect import *
from collections import *
from contextlib import redirect_stdout
from itertools import *
from math import sqrt, gcd, inf
from array import *
from functools import lru_cache
from types import GeneratorType
from heapq import *
RI = lambda: map(int, sys.stdin.buffer.readline().split())
RS = lambda: map(bytes.decode, sys.stdin.buffer.readline().strip().split())
RILST = lambda: list(RI())
DEBUG = lambda *x: sys.stderr.write(f'{str(x)}\n')
MOD = 10**9 + 7
# ms
def solve():
n, = RI()
a = RILST()
c= Counter()
ans = 0
for i,v in enumerate(a):
p = i%3
c[p] += v
if c[p] > c[ans]:
ans = p
print(['chest', 'biceps', 'back'][ans])
if __name__ == '__main__':
solve()
三、4795. 安全区域
链接: 4795. 安全区域
1. 题目描述
2. 思路分析
最好有纸笔画一下。
- 用两个set(rs,cs)来记录已记录了了哪行、哪列。
- 当增加一个车时,记录对应的行列。且分写这个车删除了本行几个点,本列几个点(注意最后分析xy点本身)。
- 当x不在rs时,代表这行里可以删除一些点,但这些点可能被其他列删过了,因此可删除的的点大概是n-len(cs)-1,但考虑一个情况,如果y在cs中,即这列已被标记了,就会多删一个点,即xy本身(我们说了,先不分析xy点本身)。
- 因此实际删除的行内点是n - len(cs) - 1 + (y in cs)。
- 讨论列同理。
- 最后讨论这个点本身,只有当xy都已标记过时,才不删除,否则要删除这个点。
- 最后别忘了标记这行列。
3. 代码实现
# Problem: 安全区域
# Contest: AcWing
# URL: https://www.acwing.com/problem/content/4798/
# Memory Limit: 256 MB
# Time Limit: 1000 ms
import sys
import bisect
import random
import io, os
from bisect import *
from collections import *
from contextlib import redirect_stdout
from itertools import *
from math import sqrt, gcd, inf
from array import *
from functools import lru_cache
from types import GeneratorType
from heapq import *
RI = lambda: map(int, sys.stdin.buffer.readline().split())
RS = lambda: map(bytes.decode, sys.stdin.buffer.readline().strip().split())
RILST = lambda: list(RI())
DEBUG = lambda *x: sys.stderr.write(f'{str(x)}\n')
MOD = 10 ** 9 + 7
# ms
def solve():
n, m = RI()
a = []
for _ in range(m):
a.append(RILST())
rs, cs = set(), set()
ans = n * n
ret = []
for x, y in a:
if x not in rs:
ans -= n - len(cs) - 1 + (y in cs)
if y not in cs:
ans -= n - len(rs) - 1 + (x in rs)
ans -= (x not in rs and y not in cs)
ret.append(ans)
rs.add(x)
cs.add(y)
print(*ret)
if __name__ == '__main__':
solve()
四、4796. 删除序列
链接: 4796. 删除序列
1. 题目描述
2. 思路分析
在值域上DP。
- 操作时会影响临近值,因此考虑打家劫舍那种DP,分类讨论邻居即可。
- 由于影响条件是x值的x-1,x+1,因此我们按值域的顺序DP即可。
- 先统计每个值出现次数,如果要这个值,就+=x*cnt[x]。
- 定义:令f[i][0/1]代表值i,不采用i/采用i的最大得分。
- 转移:
- 显然f[i][0] = max(f[i-1]),即不采用i的话,i-1采不采用都可以。
- f[i][1] = i*cnt[i] + f[i-1][0], 即采用i的话,不能采用i-1。
- 初始:f[0] = [0,0],题目值域从1开始,因此0没得采用。
- 答案:max(f[-1])
3. 代码实现
# Problem: 删除序列
# Contest: AcWing
# URL: https://www.acwing.com/problem/content/4799/
# Memory Limit: 256 MB
# Time Limit: 1000 ms
import sys
import bisect
import random
import io, os
from bisect import *
from collections import *
from contextlib import redirect_stdout
from itertools import *
from math import sqrt, gcd, inf
from array import *
from functools import lru_cache
from types import GeneratorType
from heapq import *
RI = lambda: map(int, sys.stdin.buffer.readline().split())
RS = lambda: map(bytes.decode, sys.stdin.buffer.readline().strip().split())
RILST = lambda: list(RI())
DEBUG = lambda *x: sys.stderr.write(f'{str(x)}\n')
MOD = 10 ** 9 + 7
# ms
def solve():
n, = RI()
a = RILST()
mx = max(a)
c = [0] * (mx + 1)
for x in a:
c[x] += 1
f = [[0, 0] for _ in range(mx + 1)]
for i in range(1,mx+1):
f[i][0] = max(f[i-1])
f[i][1] = f[i-1][0] + i*c[i]
print( max(f[-1]))
if __name__ == '__main__':
solve()
六、参考链接
- 无