文章目录
1 异或和:3549
1.1 题目内容
1.2 题目分析
- 树状数组 + DFS + 邻接表存储树
- 一开始DFS整棵树,记录每个节点第一次访问的num和退出访问的num。
- 得到了每个节点的[in,out],就可以计算出异或前缀和(in ~ out范围)。
- 树状数组初始化update(该结点第一次访问的num,该结点的权值),刚开始初始化为0。
- [l, r]的异或前缀和 = sums( r ) ^ sums(l - 1)。
- 更新节点:update(该结点第一次访问的num,该结点的原权值 ^ 更改后的权值)
- 异或:
0 ^ a = a
a ^ a = 0
a ^ b ^ b = a
1.3 代码部分
import os
import sys
def dfs(now, fa):
global num
num += 1
visit_num[now][0] = num
for child in tree[now]:
if child != fa:
dfs(child, now)
visit_num[now][1] = num
def lowbit(x):
return x & -x
def update(x, d):
while x <= n:
tree_list[x] ^= d
x += lowbit(x)
def sums(x):
ans = 0
while x:
ans ^= tree_list[x]
x -= lowbit(x)
return ans
n, m = map(int, input().split())
a = [0] + list(map(int, input().split()))
tree = [[] for _ in range(n + 1)]
for _ in range(n - 1):
u, v = map(int, input().split())
tree[u].append(v)
tree[v].append(u)
visit_num = [[0, 0] for _ in range(n + 1)]
num = 0
dfs(1, 0)
tree_list = [0] * (n + 1)
for i in range(1, n + 1):
update(visit_num[i][0], a[i])
for _ in range(m):
s = list(map(int, input().split()))
if s[0] == 1:
update(visit_num[s[1]][0], a[s[1]] ^ s[2])
a[s[1]] = s[2]
else:
res = sums(visit_num[s[1]][1]) ^ sums(visit_num[s[1]][0] - 1)
print(res)
2 特殊日期:2408
2.1 题目内容
2.2 题目分析
- 遍历每个日期,datetime.timedelta(1)增加每一天。
2.3 代码部分
import os
import sys
import datetime
'''
start = datetime.date(1900, 1, 1)
end = datetime.date(9999, 12, 31)
delta = datetime.timedelta(1)
num = 0
while start != end:
a = start.year
b = start.month
c = start.day
s1 = sum(map(int, list(str(a))))
s2 = sum(map(int, list(str(b))))
s3 = sum(map(int, list(str(c))))
if s1 == s2 + s3:
num += 1
start += delta
print(num)
'''
print(70910)
3 三国游戏:3518
3.1 题目内容
3.2 题目分析
- 贪心,每次取最大值。
- 分为三种情况:X胜、Y胜、Z胜。
- 根据三种情况分别将X - (Y + Z)、Y - (X + Z)、Z - (X + Y)降序排序
- 从大数开始加,x,y,x中只要有一个 > 0就加一。
3.3 代码部分
import os
import sys
n = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = list(map(int, input().split()))
a = sorted([A[i] - (B[i] + C[i]) for i in range(n)], reverse = True)
b = sorted([B[i] - (A[i] + C[i]) for i in range(n)], reverse = True)
c = sorted([C[i] - (A[i] + B[i]) for i in range(n)], reverse = True)
ans = 0
x, y, z = 0, 0, 0
for i in range(n):
x += a[i]
y += b[i]
z += c[i]
if x > 0 or y > 0 or z > 0:
ans += 1
print(ans if ans != 0 else -1)
4 翻转:3520
4.1 题目内容
4.2 题目分析
- 从第二个数开始判断,左边和右边相等且与当前数不同,则变换数字。
- (首位如果不同,一定不存在方案。)
- 判断变换后的字符串S是否和字符串T一致。
4.3 代码部分
import os
import sys
d = int(input())
for i in range(d):
t = list(input())
s = list(input())
ans = 0
for j in range(1, len(t) - 1):
if s[j] == t[j]: continue
elif s[j - 1] == s[j + 1] and s[j] != s[j + 1]:
s[j] = s[j + 1]
ans += 1
if s == t: print(ans)
else: print(-1)
5 平均:3532
5.1 题目内容
5.2 题目分析
- 贪心
- 排序,从最小的开始取,取times个。
5.3 代码部分
import os
import sys
n = int(input())
times = n // 10
nums = [[] for _ in range(10)]
for i in range(n):
a, b = map(int, input().split())
nums[a].append(b)
ans = 0
for i in range(10):
n = sorted(nums[i])
ans += sum(n[: -times])
print(ans)
6 分糖果:2928
6.1 题目内容
6.2 题目分析
- 根据题意得,分给所有同学的字符串中,存在一个字典序列最大的字符串,要求出所有情况中,这个字典序列最大的字符串的最小值。
- 首先将字符串排序。
- 分为三种情况:
① 所有糖果相同。将所有糖果均分,字典序最大的字符串即为:(每个人分的个数 + 1(余数)) * [字符]。
② 所有糖果不相同,第一种糖果够分给所有同学。每名同学都分1个第一种糖果后,将剩下的所有糖果都分给一个人。
③ 所有糖果不相同,第一种糖果不够分给所有同学。第一轮中,最后一个分到糖果的同学,当前他所拥有的糖果字典序最大,将所有剩下的糖果都给他。
6.3 代码部分
import os
import sys
n, x = map(int, input().split())
s = list(input())
s.sort()
if len(set(s)) == 1:
if n % x == 0:
ma = (n // x) * s[0]
else:
ma = (n // x + 1) * s[0]
elif s.count(s[0]) >= x:
ma = s[0] + "".join(s[x: ])
else:
ma = s[x - 1]
print(ma)
总结
未完待续…