A. Dr. TC
https://codeforces.com/contest/2106/problem/A
题目大意:
对输入字符串每个位置字符依次翻转(1->0 , 0->1)
比如: 101
001 翻转位置1
111 2
100 3
题解:
观察数学特征:ans=n1*(n-1)+n0
t=int(input())
for i in range(t):
n=int(input())
s=input()
n1=s.count('1')
n0=s.count('0')
print(n1*(n-1)+n0)
B. St. Chroma
https://codeforces.com/contest/2106/problem/B
题目大意:
需要构造长为n的数组a,包含0到n-1各一个
然后填涂一个新数组b:从左到右第 i 个位置等于MEX(a[ : i ])
MEX:该序列中第一个未出现的非负整数
现在每个测试案例给n,x,要求b中x的最大可能数
题解:
贪心策略:前面尽快填补0到x-1,然后x得最后出
注意特判:n==x时,按照上面的贪心策略会导致多多余一个元素,正确做法是0到n-1按序填补
t=int(input())
for i in range(t):
n,x=map(int,input().split())
if n!=x:
l1=[j for j in range(x)]
l2=[j for j in range(x+1,n)]
l3=l1+l2+[x]
print(*l3)
else:
l=[j for j in range(n)]
print(*l)
C. Cherry Bomb
https://codeforces.com/contest/2106/problem/C
题目大意:
每个案例输入n和k
再给a,b两个数组(n是他们的长度),其中a的元素已经固定,b中-1的位置表示可以随意变,范围是 [ 0 , k ] 左闭右开
要求a,b各个相对应的位置相加的和一致,输出有几种配合方式,如果没有可能就输出0
题解:
先过一遍统计一下b中不是-1的位置的和
如果不是一致的就可以直接输出0了,
如果一致也别开心太早:
由于a中元素x在添加[ 0 , k ]后区间为[ x , x + k ],su要在这区间中
从极端情况考虑就是if mx<=mn+k and mx<=su[0]<=mn+k:(得利用and短路的特性,判断顺序不能换)
可能a中最小值比和小或者最大值比和大:还是0
否则的话就输出1,因为和已经固定了
如果没有一个和的话那就贪心:a中最大最小值限定了范围上下限,同时还被k限定
观察后得到ans=k+mn-mx+1
t=int(input())
for i in range(t):
n,k=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
su=[]
for j in range(n):
if b[j]!=-1:
su.append(a[j]+b[j])
if su:
if su[0]!=sum(su)/len(su):
print(0)
continue
else:
mn=min(a)
mx=max(a)
if mx<=mn+k and mx<=su[0]<=mn+k:
print(1)
else:
print(0)
else:
mx=max(a)
mn=min(a)
if mx>mn+k:
print(0)
else:
print(k+mn-mx+1)
但是是错的
贪心个屁,还不如直接模拟
t = int(input())
for _ in range(t):
n, k = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
target = None
cnt_missing = 0
for i in range(n):
if b[i] != -1:
curr_sum = a[i] + b[i]
if target is None:
target = curr_sum
elif target != curr_sum:
print(0)
break
else:
cnt_missing += 1
else: # 没有break才会执行
if target is None: # b全是-1的情况
max_a = max(a)
min_a = min(a)
if max_a > min_a + k: # 差值太大,无解
print(0)
else:
ans = min_a + k - max_a + 1
print(max(0, ans))
else:
# 已知target,检查所有-1位置填入的值是否在范围内
valid = True
for i in range(n):
if b[i] == -1:
bi = target - a[i]
if bi < 0 or bi > k:
valid = False
break
'''
mn=min(a)
mx=max(a)
if mn>target or mx
'''
print(1 if valid else 0)
D. Flower Boy
https://codeforces.com/contest/2106/problem/D
题目大意:
一个长度为n的数组a,一个长度为m的数组b,按左到右的顺序遍历a,选出m个数,选出的第i个不小于b[i],现在有种只能进行一次的操作,可以在a中任意位置插入一个任意整数k,如果不插入就能选m个就输出0,如果插入后仍不能选m个就输出-1,否则求最小k
注意:题面说“从左到右”并不是连续,所以m朵花可以是跳跃的
题解:
首先构造check函数模拟选花的过程
判断原来数组不插入可以的话直接输出0
二分查找k值
枚举所有可插入位置
def solve():
n, m = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
def check(arr, b):
bi = 0
for val in arr:
if bi < len(b) and val >= b[bi]:
bi += 1
return bi == len(b)
if check(a, b):
print(0)
return
left = 1
right = max(max(a), max(b))
ans = -1
while left <= right:
mid = (left + right) // 2
possible = False
for i in range(n + 1):
temp_a = a[:]
temp_a.insert(i, mid)
if check(temp_a, b):
possible = True
break
if possible:
ans = mid
right = mid - 1
else:
left = mid + 1
print(ans)
t = int(input())
for _ in range(t):
solve()
做到D感觉就太累了,也许题面是中文、时间再早点还能a一下,我还是练太少了