LoginSignup
0
0

ABC338の記録

Last updated at Posted at 2024-01-27

はじめに

「NEW GAME!」のことはちゃんと好きなので「ぞいです」はちょっと抵抗ある。青葉ちゃんが元ネタなのか知りませんが。

成績:ABC3完(600)

A

全部文字コードに変換して1文字目が大文字か、それ以降が全部小文字かどうかを確かめた。sが1文字目だけのパターンもあるのでそれだけ注意する。

A
s = input()
if 90 >= ord(s[0]) >= 65:
    for i in range(1,len(s)):
        if 90 >= ord(s[i]) >= 65:
            print("No")
            break
    else:
        print("Yes")
else:
    print("No")

「大文字か小文字かを判定する関数ってないのかな~」と考えながら解いてたが、あるらしいです。

A'
s = input()
if len(s) == 1:
    if s.isupper() == True:
        print("Yes")
    else:
        print("No")
else:
    if s[0].isupper() and s[1:].islower(): 
        print("Yes")
    else:
        print("No")

B

長さが26の配列を作り、それぞれのアルファベットの登場回数に対応させる。sを1文字ずつ見ていって、登場したアルファベットに対応するリストの要素に1足していく。

B
s = input()
#26個のリストlsを作り、ls[0]がa、ls[1]がb……ls[25]がzの個数となるようにしていく。
ls = [0]*26
#sを一文字ずつ見ていき、ls[ord(s[i])-97]に1を足す。
for i in range(len(s)):
    ls[ord(s[i])-97] += 1
#この最大値が最も多く出現するアルファベット。
ans = ls.index(max(ls))
print(chr(ans+97))

C

まずAの料理を作れるだけ作ってそのあまりの材料で作れるBの料理の数を求めて、合計を出す。
その後、Aの料理が作れなくなるまで1つずつ減らしていき、合計が一番高い時の値を出力する。
作れる料理の数については、今ある食材のリストQと料理に必要な食材のリストAを引数に取り、Qの各要素をAの各要素で割った値の最小値を取る関数を定義することで対応した。

C
n = int(input())
Q = list(map(int,input().split())) #冷蔵庫にある材料の量
A = list(map(int,input().split())) #料理Aを作るのに必要な材料の量
B = list(map(int,input().split())) #料理Bを作るのに必要な材料の量
ls = [0]

def cook(Q,A): #材料リストと必要食材リストを引数に取る関数を定義する。
    Anum = []
    for i in range(n):
        if A[i] == 0:
            Anum.append(10000000)
        else:
            Anum.append(Q[i]//A[i])
    return(min(Anum)) #指定した材料リストで作れる料理の個数を返す。
ans = 0
ansA = cook(Q,A)
Qn = [Q[i]-ansA*A[i] for i in range(n)]
ansB = cook(Qn,B)
if ansA+ansB > ans:
    ans = ansA+ansB
#ansAを1減らしてみるとどうなる?→これをansAが0になるまでやればいい。
while ansA >= 0:
    ansA -= 1
    Qn = [Q[i]-ansA*A[i] for i in range(n)]
    ansB = cook(Qn,B)
    if ansA+ansB > ans:
      ans = ansA+ansB
print(ans)

Dは解説をチラ見したところ面白そうなのでなんとか解いてみたい。解いたら追記しようかな。
(2024/01/28 3:00追記)

まず1とNの間の橋を封鎖した場合を考える。この時、ツアーの長さは$X[i+1]-X[i]$を足していけば求まる。
この後封鎖する橋を一つずつ動かしていくが、それぞれの区間について「どの橋を封鎖したときに長さがいくつ変化するか」をあらかじめ計算しておく。
各区間の移動方法は時計回りと反時計回りのいずれかしかないことから、それぞれの区間の移動にかかる長さは$X[i+1]-X[i]$もしくは$N-(X[i+1]-X[i])$なので、長さの変化はこの差から求められる。
この変化の累積和を求めて、その最小値をdと足せばOK。

D
n, m = map(int,input().split())
X = list(map(int,input().split()))
d = 0
for i in range(m-1):
    d += abs(X[i+1]-X[i])
change = [0]*(n+1) #橋の数なのでnだが、島の番号と合わせた方が計算しやすいのでn+1個。
for i in range(m-1): #ツアーの行程の数なのでm-1
    change[min(X[i],X[i+1])] += n-2*(abs(X[i+1]-X[i])) #封鎖後の長さ-封鎖前の長さ
    change[max(X[i],X[i+1])] += 2*(abs(X[i+1]-X[i]))-n #封鎖前の長さ-封鎖後の長さ
ans=[]
for i in change:
    ans.append(d+i)
    d += i
print(min(ans))

難しい。封鎖する橋をずらしていくという発想にたどり着いたうえでそこから累積和を使えないといけない。これを数十分で解けるようになるのは目標としては高すぎると思うので、出来ることからコツコツと。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0