sima(mu)*雑記

print(f"{雑多なこと}")

ABC109参加記

AtCoder Beginner Contest 109 - AtCoder
コンテスト時間: 2018-09-08(土) 21:00 ~ 2018-09-08(土) 22:40 f:id:awaawa4423:20180908212848p:plain
20:30で全完0WA全体39位でした.unRatedだけど全体順位は今までで一番良かった.

A - ABC333

かけたら奇数になるのは奇数×奇数だけなので,A*Bが奇数かどうかだけ見ればよい

A,B = map(int,input().split())
if (A*B)%2 == 0:
  print('No')
else:
  print('Yes')

B - Shiritori

しりとりをします.
同じ単語が含まれているかどうかはset()で持って配列長が変化するかどうか見ればよい(これ昨日のyukicoderで同じことした)
pythonなら文字列や配列の末尾はS[-1]で指定できる

import sys
N = int(input())
ww = [input() for i in range(N)]

if len(set(ww)) != N:
    print('No')
else:
    for i in range(N-1):
        a = ww[i]
        b = ww[i+1]
        if a[-1] != b[0]:
            print('No')
            sys.exit()
    print('Yes')

C - Skip

何をすればいいかは見ればわかったけど改めてなんでって言われると難しい…
全ての都市と出発点をx座標でソートした時隣り合う都市間の距離がDで割り切れれば全ての都市に行けるので,隣接二点間の距離全体の最大公約数を求めればよい.
最大公約数はユークリッドの互除法を使えば十分高速に求まる

N,X = map(int, input().split())
xx = sorted(list(map(int, input().split())) + [X])

dists = set()
for i in range(N):
    dists.add(xx[i+1]-xx[i])
dists = sorted(list(dists))

def gcd(a,b):
    while b:
        a,b = b, a%b
    return a

ans = dists[0]
for d in dists:
    ans = gcd(ans,d)

print(ans)

D - Make Them Even

こういう問題すき
奇数マスを2つずつになるように上手くペアを選んでそれぞれ結んであげれば, その結んだ線上の経路をたどって一枚のコインを一方からもう一方に動かせばよい.
問題は同じマスを2回選べないのでこの経路が被ってはいけない.
ではどうするかというと,一筆書きとなるようにマス全体を辿っていき,辿っていく中で隣接する二つの奇数マスの間でコインを動かせば経路が被らない.
コインを動かすという動作をコインを拾い,持ち歩き,落とす,と言い直して凄くざっくり書くと

if 奇数マスにいる:
    if コインを持っている:
        コインを落とす
    else:
        コインを拾う

として,コインを持って歩いたところがコインを動かすところとなる.
また,全マスなめるように一筆書きするのはS字に辿ればよい.
[0,N)ひっくり返した区間が欲しいときはrange(N-1,-1,-1)とかよりはreversed(range(N))の方が簡単だし,辺に足し引きしなくて済むので楽です

def inpl(): return list(map(int, input().split()))

H,W = inpl()
MAP = [inpl() for i in range(H)]

flag = False #コインを持っているか
ans = []
for y in range(H):
    if y%2 == 0:
        xx = range(W)
    else:
        xx = reversed(range(W))
    for x in xx:
        if flag:
            ans.append([by,bx,y,x])
        if MAP[y][x]%2 == 1:
            flag = not flag
        bx,by = x,y

print(len(ans))
for a,zu,nya,n in ans:
    print(a+1,zu+1,nya+1,n+1)

最後の出力が一行に複数出力するタイプの奴,出力用の変数で遊びませんか?
問題文上は1indexなので出力する時は+1を忘れずつけましょう
手数の最小化という条件が付いたら一気に難しくなりそう

感想

unratedだったけどABConlyで全体39位はなかなか健闘したのではー?
情報系の学部じゃないのでソースコード書き慣れてないせいか,やっぱり手が止まるのは実装の方って感じがする.(精進して
D問題はとても好きですって感じでした