A. Array Divisibility
从1打印到n就行了,k的倍数相加仍是k的倍数
B. Corner Twist
模拟
可以发现,每次操作会使某两行和两列总和加三,即不改变每行和每列模3的余数,那么只要a和b每行和每列的模3的余数相同,遍历a,每次将a中的一个元素变为最终结果,最后总可以变为b
def check():
h, l = [0] * n, [0] * m
for i in range(n):
for j in range(m):
h[i] += mp1[i][j] - mp2[i][j]
l[j] += mp1[i][j] - mp2[i][j]
for i in range(n):
if (h[i]+3) % 3 != 0:
return False
for j in range(m):
if (l[j]+3) % 3 != 0:
return False
return True
t = int(input())
for _ in range(t):
n, m = map(int, input().split())
mp1 = [list(map(int, list(input()))) for _ in range(n)]
mp2 = [list(map(int, list(input()))) for _ in range(n)]
if check():
print('YES')
else:
print('NO')
C. Have Your Cake and Eat It Too
模拟,二分
将蛋糕划分为三份,要求每个人蛋糕的和都要大于tot/3上取整,
可以发现,a b c分蛋糕顺序总共只有6种情况,分别求每种情况,看是否能分
前缀和优化,二分中间切蛋糕的两个位置,并判断是否符合
from bisect import *
def check(s1, s2, s3):
ra = bisect(s1, avg)
if ra != 0 and s1[ra-1] == avg:
ra -= 1
# print(ra)
if ra >= n-1:
return 0
rb = bisect(s2, avg+s2[ra])
if rb != ra+1 and s2[rb-1] == avg+s2[ra]:
rb -= 1
# print(rb)
if ra+1 <= rb < n and tot-s3[rb] >= avg:
return 1, ra, ra+1, rb, rb+1, n
else:
return 0
def solve():
ck = check(a, b, c)
if ck:
l1, r1, l2, r2, l3, r3 = ck
return l1, r1, l2, r2, l3, r3
ck = check(a, c, b)
if ck:
l1, r1, l2, r2, l3, r3 = ck
return l1, r1, l3, r3, l2, r2
ck = check(b, c, a)
if ck:
l1, r1, l2, r2, l3, r3 = ck
return l3, r3, l1, r1, l2, r2
ck = check(b, a, c)
if ck:
l1, r1, l2, r2, l3, r3 = ck
return l2, r2, l1, r1, l3, r3
ck = check(c, a, b)
if ck:
l1, r1, l2, r2, l3, r3 = ck
return l2, r2, l3, r3, l1, r1
ck = check(c, b, a)
if ck:
l1, r1, l2, r2, l3, r3 = ck
return l3, r3, l2, r2, l1, r1
return -1
t = int(input())
fal = [0]*6
for _ in range(t):
n = int(input())
a = [0]+list(map(int, input().split()))
b = [0]+list(map(int, input().split()))
c = [0]+list(map(int, input().split()))
tot = sum(a)
avg = (tot + 2) // 3
# print(tot, avg)
for i in range(1, n+1):
a[i] += a[i-1]
b[i] += b[i-1]
c[i] += c[i-1]
res = solve()
if res == -1:
print(-1, end=" ")
else:
for i in range(6):
print(res[i], end=" ")
print()
D. Swap Dilemma
数学,贪心,归并排序
若a,b中每种元素个数不同,一定不行
同时移动a,b相同下标的元素一定是合法的,将a,b按以a大小为关键字排序,方便计算
a为递增,将b调整为递增形式,可以发现每次只选择r-l=1,即只移动相邻的元素,就能将b调整为a
每两次移动在a中抵消,最后b调整完毕后,看a能否完全抵消,b调整次数即逆序数,归并排序计算逆序数,判断逆序数是否能整除2即可
def inv_num(lis, l, r):
if l >= r:
return 0
mid = (l + r) // 2
res = inv_num(lis, l, mid) + inv_num(lis, mid + 1, r)
i, j, tmp = l, mid + 1, []
while (i <= mid) and (j <= r):
if lis[i] <= lis[j]:
tmp.append(lis[i])
i += 1
else:
tmp.append(lis[j])
res += mid - i + 1
j += 1
tmp += lis[i:mid + 1]
tmp += lis[j:r + 1]
lis[l:r + 1] = tmp
return res
def check():
if sorted(a) != sorted(b):
return False
lis = [(a[i], b[i]) for i in range(n)]
lis.sort()
lis2 = [lis[i][1] for i in range(n)]
rev = inv_num(lis2, 0, n-1)
return rev % 2 == 0
t = int(input())
for _ in range(t):
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
if check():
print("YES")
else:
print("NO")