链接: A - Alternately
# Problem: A - Alternately
# Contest: AtCoder - AtCoder Beginner Contest 296
# URL: https://atcoder.jp/contests/abc296/tasks/abc296_a
# Memory Limit: 1024 MB
# Time Limit: 2000 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 array import *
from functools import lru_cache
from types import GeneratorType
from heapq import *
from math import sqrt, gcd, inf
if sys.version >= '3.8': # ACW没有comb
from math import comb
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
PROBLEM = """https://atcoder.jp/contests/abc296/tasks/abc296_a
给你整数n和长为n的字符串s
s由M/F两种字母组成代表男女。
检测s是否是男女交替的。
"""
def solve():
n, = RI()
s, = RS()
for i in range(n - 1):
if s[i] == s[i + 1]:
return print('No')
print('Yes')
链接: B - Chessboard
PROBLEM = """https://atcoder.jp/contests/abc296/tasks/abc296_b
给你一个8*8的棋盘。由'.*'两种字符组成。
棋盘上只有一个*,找出*的坐标。
其中横坐标从下往上编码为1-8;纵坐标从左到右编码为a-h。
"""
# ms
def solve():
g = []
for _ in range(8):
s, = RS()
g.append(s)
for i in range(8):
for j, c in enumerate(g[i]):
if c == '*':
a = chr(ord('a') + j)
print(f"{a}{8 - i}")
链接: C - Gap Existence
PROBLEM = """https://atcoder.jp/contests/abc296/tasks/abc296_c
给你整数N(2<=N<=2e5),X(-1e9<=X<=1e9),和长为N的数组A。
请问A中是否存在两个数差值为X。这两个数可以是同一个数。
"""
# ms
def solve():
n, x = RI()
a = set(RILST())
for v in a:
if v - x in a or v + x in a:
return print('Yes')
print('No')
链接: D - M<=ab
PROBLEM = """https://atcoder.jp/contests/abc296/tasks/abc296_d
给你两个正整数n,m(1<=N,M<=1e12)。
找到一个最小的x,使x满足:
1.x>=m
2.x可以被分解为两个数ab的乘积,其中1<=a,b<=n
"""
# ms
def solve():
n, m = RI()
if n * n < m:
return print(-1)
if n * n == m:
return print(m)
if m <= n:
return print(m)
s = int(m ** 0.5)
ans = n * n
for a in range(2, min(s, n) + 1):
b = (m + a - 1) // a
if b <= n:
ans = min(ans, b * a)
print(ans)
链接: E - Transition Game
这题读题没读懂,就去做F了,赛后补的E。主要是没看懂那个x是哪来的,后来知道写在黑板上的数就是x。而且黑板上每次只有一个数。
值作为下标
->值
这个路径往后走,路径可以用图考虑。PROBLEM = """https://atcoder.jp/contests/abc296/tasks/abc296_e
给你N和长度为N的数组a,其中1<=a[i]<=N,下标从1开始。
A和B做N轮游戏,轮数下标从1开始。在第i轮,玩法如下:
1. A指定一个正整数ki,告诉B。
2. B指定一个1~N之间的数,写在黑板上。
3. 做如下操作ki次:把黑板上的数字x替换成a[x]。
操作结束后,如果黑板上的数字是i,B赢;否则A赢。
请问在A和B都做最优操作的情况下,B能赢多少次。
"""
# ms
def solve():
n, = RI()
a = RILST()
g = [[] for _ in range(n + 1)]
degree = [0] * (n + 1)
for i, v in enumerate(a, start=1):
g[i].append(v)
degree[v] += 1
q = deque([i for i, v in enumerate(degree) if i and v == 0])
ans = n
while q:
ans -= 1
u = q.popleft()
for v in g[u]:
degree[v] -= 1
if degree[v] == 0:
q.append(v)
print(ans)
链接: F - Simultaneous Swap
群里大佬说正解是逆序对,我没看懂,直接找性质做的。没想到直接交就TLE了,优化了一下就过了
这里吐槽一下for x in set:break 是会TLE的,看来虽然提前break但没用,依然是O(n)。
PROBLEM = """https://atcoder.jp/contests/abc296/tasks/abc296_f
给你N(3<=N<=2e5),和两个长度为n的数组a,b。
你可以做如下操作任意次或不做:
选下标j!=i!=k,同时交换:在a中交换a[i]a[j].再b中交换b[i]b[k]
若可以使a完全等于b输出Yes,否则输出No。
"""
# ms
def solve():
n, = RI()
a = RILST()
b = RILST()
if a == b:
return print('Yes')
if sorted(a) != sorted(b):
return print('No')
if len(set(a)) < n:
return print('Yes')
posa = {v: i for i, v in enumerate(a)}
posb = {v: i for i, v in enumerate(b)}
left = set(a)
def get(x, y):
s = set()
ans = 0
nonlocal left
for _ in range(3):
p = left.pop()
if x != p != y:
ans = p
s.add(p)
left |= s
return ans
for i in range(n - 2):
if a[i] == b[i]:
left.remove(a[i])
else:
v = get(a[i], b[i])
pa = posa[v]
pb = posb[v]
left.remove(v)
posa[a[i]] = pa
posb[b[i]] = pb
a[pa] = a[i]
b[pb] = b[i]
if a[-1] == b[-1] and a[-2] == b[-2]:
return print('Yes')
print('No')