注:个人补题记录 ,按难度排序
G、Problem - G - Codeforces
G是签到题比较简单看题面:
根据题意我们可以知道,我们只要统计Fibonacci数列前n项里面有多少个奇数和偶数就能算出答案,找规律就行。上ac代码
import sys
n = int(sys.stdin.readline())
ans = 0
a,b,num =n-3,n%3, n//3
ans += (a+b)*num//2
ans += (num + 1)*num
print(ans)
M、Problem - M - Codeforces
题目定义是思维题,看题面:
题目大意是说每组样例给你n和m个由‘/’分割的字符串,前n个是需要 ignored的后m个不能被 ignored,问我们最少 ignored几次能完成。就像删文件夹,一个文件夹里面如果全部都要删,那我们直接删一次总文件夹就好,负责就得将需要删的子文件夹一个一个删。理解题意之后就很容易想到递归统计我们需要的处理的次数,而建树的话,我们定义一个节点类建字典树就好。
上pypy3AC代码:
import sys
class Node:
def __init__(self, name, ignore):
self.name = name
self.ignore = ignore
self.sons = {}
def addson(self, name, ignore):
if name in self.sons:
self.sons[name].ignore = ignore
return self.sons[name]
x = Node(name,ignore)
self.sons[name] = x
return x
def solve():
n, m = map(int, sys.stdin.readline().split())
root = Node('', False)
for _ in range(n):
s = sys.stdin.readline().strip().split('/')
now = root
for x in s:
now = now.addson(x, True)
for _ in range(m):
s = sys.stdin.readline().strip().split('/')
now = root
for x in s:
now = now.addson(x, False)
def getans(x):
if x.ignore:
return 1
ans = 0
for name,y in x.sons.items():
ans += getans(y)
return ans
print(getans(root))
for _ in range(int(sys.stdin.readline())):
solve()
B、Problem - B - Codeforces
B题也是到思维吧,狠狠的考智商和思维灵活,算是由CF内味了。
这题很容易想的是搜索,但emmmmm,改一个影响周围一圈,这个数据大小肯定TLE啊QAQ。后面想了想要是a和b不同的个数小于那直接变成a不就好了,然后又想到对于 . 和X的关系是没有方向的所以,如果不同的字符超过
,那我们就把a取反输出就好了,看代码:
import sys
n,m = map(int, sys.stdin.readline().split())
a,b = [], []
for i in range(n):
a.append(sys.stdin.readline().strip())
for i in range(n):
b.append(sys.stdin.readline().strip())
ans = (n*m)>>1
cnt1,cnt2 = 0, 0
for i in range(n):
for j in range(m):
if a[i][j] == b[i][j]: cnt1+=1
else: cnt2 += 1
if cnt2 <= ans:
for i in range(n):
for j in range(m):
print(a[i][j],end = '')
print()
else:
for i in range(n):
for j in range(m):
if a[i][j] == '.': print('X',end = '')
else: print('.',end = '')
print()
D、Problem - D - Codeforces
题目大意是给我们两个人的初始位置和速度,再给我们整个轴的长度,让我们求最少需要多少时间才能让每个位置都至少有一个人走过。
这是官方题解原话,我们可以分几类来考虑这个问题:
1. 一个人把所有地方走完;
2. 两个人对穿,也就是说他们互相往另一个人的方向走,直到边界;
3. 两个人各负责自己的一边,然后在中间相遇,那么对于每个人,有两种选择,一种是先往端点走,一种是先往中间走,那么我们可以二分时间,就能够算出每个人往中间最多能走多少路,判断一下能不能把线段覆盖了就行啦!
前两点我们很好理解,主要说说最后一点:我们二分时间,然后计算两个人走的互不交叉并且各包含一个端点的最长路径,就是计算出时间T的情况下,p1和p2的两个人在自己那边能覆盖多少,两个覆盖的长度大于n就表示覆盖完了。
详细解析可以见下面两张图片:
接下来上ac的python3代码:
import sys
def solve():
n,p1,v1,p2,v2 = map(float, sys.stdin.readline().split())
if p1 > p2: p1,p2,v1,v2 = p2,p1,v2,v1
#一人全走完
ans = min((min(p1,n-p1) + n)/v1, (min(p2,n-p2) + n)/v2)
#两人相向走直到边界
ans = min(ans, max((n-p1)/v1, p2/v2))
#两人各负责自己的一边,二分时间
l,r,res = 0,1e9,0
for i in range(200):
t = (l+r)/2
l1,l2 = v1*t,v2*t
d1,d2 = max((l1+p1)/2, l1-p1), max((n-p2+l2)/2, l2-(n-p2))
if d1 < p1: d1 = 0
if d2 < n-p2: d2 = 0
if d1 + d2 >= n: #时间多了
res = t
r = t
else: l = t
ans = min(res, ans)
print(ans)
for _ in range(int(sys.stdin.readline())):
solve()