あるぱかのブログ

AtCoder茶(レート566)

日本レジストリサービス(JPRS)プログラミングコンテスト2024#2(AtCoder Beginner Contest 364)

rated

atcoder.jp

A - Glutton Takahashi

リンク:A - Glutton Takahashi (atcoder.jp)

概要:甘い料理を2連続食べるとギブアップします。すべての料理を食べきれるか判定してね。

"sweet"と"salty"の2種類が入力として与えられるので"sweet"が2連続で出現したときにギブアップします。

ここでは前回食べた料理をpreに記録し、今から食べる料理sと2つ続けて"sweet"が来たらギブアップしています。

(コンテスト中は食べられる料理の数を出力かと思って書いてた名残で変なことしてます)

#ABC364 A - Glutton Takahashi
N = int(input())
pre = input()
judge = True
if N <= 2:
    print('Yes')
    exit()
for _ in range(N-2):
    s = input()
    if pre == s == 'sweet':
        judge = False
        break
    pre = s
if judge:
    print('Yes')
else:
    print('No')  

提出リンク:A - Glutton Takahashi (atcoder.jp)

B - Grid Walk

リンク:B - Grid Walk (atcoder.jp)

概要:グリッド上を”LRUD"で与えられる指示の通り歩きます。最後の指示を終えた時の場所を教えてね

制約も厳しくないのでシミュレートします。

今いる位置を (s_i, s_j)として次に (s_i+dx, s_j+dy)に進むことにします。

指示が"U"(1つ上)なら (dx, dy)=(-1, 0)、"R"(1つ右)なら (dx, dy)=(0, 1)という風に次に進む向きを指示します。

進む先がグリッド外もしくは壁"#"ならその場にとどまるようにします。

進めるなら (s_i, s_j) (s_i+dx, s_j+dy)に更新します。

 i,j x,yが上下どちらか混乱しないように注意が必要です。

#ABC364 B - Grid Walk
H, W = map(int, input().split())
si, sj = map(int, input().split())
si -= 1
sj -= 1
C = [input() for _ in range(H)]
X = input()
for i in range(len(X)):
    dx = 0
    dy = 0
    if X[i] == 'L':
        dy -= 1
    elif X[i] == 'R':
        dy += 1
    elif X[i] == 'U':
        dx -= 1
    elif X[i] == 'D':
        dx += 1
    if si+dx < 0 or H-1 < si+dx or sj+dy < 0 or W-1 < sj+dy:
        continue
    if C[si+dx][sj+dy] == '.':
        si += dx
        sj += dy
print(si+1, sj+1)  

提出リンク:提出 #56020261 - 日本レジストリサービス(JPRS)プログラミングコンテスト2024#2(AtCoder Beginner Contest 364)

C - Minimum Glutton

リンク:C - Minimum Glutton (atcoder.jp)

概要: N個の料理に甘さ A_iとしょっぱさ B_iが設定されています。甘さの合計が Xを超える、もしくはしょっぱさの合計が Yを超えるとギブアップします。料理を好きな順番で食べられる場合に食べる料理の数の最小値を出力してね。

甘さでギブアップする場合としょっぱさでギブアップする場合の2通りを考えて食べる料理の数を比較します。

甘さの配列 Aとしょっぱさの配列 Bを大きい順にソートして順に食べ、どちらかが閾値を超えたときに食べた数を出力します。

#ABC364 C - Minimum Glutton
N, X, Y = map(int, input().split())
A = sorted(list(map(int, input().split())), reverse = True)
B = sorted(list(map(int, input().split())), reverse = True)
ama = 0
kara = 0
for i in range(N):
    ama += A[i]
    kara += B[i]
    if ama > X or kara > Y:
        break
print(i+1)  

提出リンク:提出 #56023754 - 日本レジストリサービス(JPRS)プログラミングコンテスト2024#2(AtCoder Beginner Contest 364)

D - K-th Nearest

リンク:D - K-th Nearest (atcoder.jp)

概要:配列 Aに対して B_iから k番目に遠い点 A_jまでの距離を Q回出力してね

点もクエリの数も多いので毎回全探索はできないので効率的な探索を考える必要があります。

探索、 k番目ということで答えで二分探索を行うとよさそうです。

以下の方針で進めます。

  • 答えを dと仮定する。 B_i-dから B_i+dの間にある Aの要素数を調べて kに対する大小を比較する。
    •  B_i-d以上となる最小の A_j B_i+d以下となる最大の A_kを二分探索で見つける。
  • 条件を満たすなら答えに記録して dを更新し次へ

44~45行目で探索の初期値として -1 10^{9}を設定していますが、 d=-1のときは明らかに条件を満たさない、 d=10^{9}のときは明らかに条件を満たす、というところから決めています。

要素を探す二分探索の部分はPythonならbisectが使えると思います。

(私は自分で書いたものを使っていて、範囲外の返り値がヘタクソなので場合分けをしています。)

#ABC364 D - K-th Nearest
def lower(A, N): #超えない最大
    l = 0
    r = len(A)-1
    if A[r] <= N:
        return r
    if A[0] > N:
        return -1
    ans = 0
    while l+1 < r:
        mid = (l+r)//2
        if A[mid] <= N:
            ans = mid
            l = mid
        else:
            r = mid
    return ans
def upper(A, N): #超える最小
    l = 0
    r = len(A)-1
    if A[r] < N:
        return -1
    if A[0] >= N:
        return 0
    ans = r
    while l+1 < r:
        mid = (l+r)//2
        if A[mid] >= N:
            ans = mid
            r = mid
        else:
            l = mid
    return ans
N, Q = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
for _ in range(Q):
    b, k = map(int, input().split())
    if b < A[0]:
        print(A[k-1]-b)
    elif b > A[-1]:
        print(b-A[-k])
    else:
        l = -1
        r = 10**9
        ans = 10**9
        while l+1 < r:
            mid = (l+r)//2
            left = upper(A, b-mid)
            right = lower(A, b+mid)
            num = right-left+1
            if num >= k:
                ans = min(ans, mid)
                r = mid
            else:
                l = mid
      print(ans)  

提出リンク:提出 #56139183 - 日本レジストリサービス(JPRS)プログラミングコンテスト2024#2(AtCoder Beginner Contest 364)