d_tail's blog

備忘や記録

【参加記録】AtCoder Beginner Contest 119

はじめに

AtCoder Beginner Contest 119に参加した記録です.

atcoder.jp

A - Still TBD

入力を'/'で分けて項目ごとに比較. なぜか7分も溶かしてしまいました.

S = input()
S = S.split('/')

if int(S[0]) <= 2019 and int(S[1]) <= 4 and int(S[2]) <= 30:
    print('Heisei')
else:
    print('TBD')

わざわざ分けなくても単純に辞書順で比較できるそうです.以下解説コード.

S = input()
print('Heisei' if S <= '2019/04/30' else 'TBD')

B - Digital Gifts

入力をループで回して加算していく.単位がBTCだったら380000.0を乗算したものを加算.

N = int(input())
in_num = []
for i in range(N):
    in_num.append(list(map(str,input().split())))

res = 0

for x,u in in_num:
    if u == 'JPY':
        res+=float(x)
    else:
        res+= float(x)*380000.0

print(res)

C - Synthetic Kadomatsu

時間内に解けず.
解説によると,N本の竹に対して,ABCの竹に使うかどれにも使わないかの4通りの使い方を全探索すれば良いらしいです.
解説ではDFSを使用していました.
以下解説コードに自分用にコメントを追加したもの.

N, A, B, C = map(int, input().split())
l = [int(input()) for i in range(N)]
INF = 10 ** 9

def dfs(cur, a, b, c):
    '''
    深さがNだったら使用MPを評価
    N本の竹を使うときに必要な合成回数はN-1のため,最後に-1*10*3(?)
    1本も竹を使用していなかったら棄却→MPを無限に使うこととしている
    '''
    if cur == N:
        return abs(a - A) + abs(b - B) + abs(c - C) - 30 if min(a, b, c) > 0 else INF

    '''
    cur番目の竹に対して
        ret0:ABCどれにも使わない
        ret1:Aに使う(合成:MP+10)
        ret2:Bに使う(合成:MP+10)
        ret3:Cに使う(合成:MP+10)
    '''
    ret0 = dfs(cur + 1, a, b, c)
    ret1 = dfs(cur + 1, a + l[cur], b, c) + 10
    ret2 = dfs(cur + 1, a, b + l[cur], c) + 10
    ret3 = dfs(cur + 1, a, b, c + l[cur]) + 10
    return min(ret0, ret1, ret2, ret3)
print(dfs(0, 0, 0, 0))

なんとなく作成してみた図(https://www.draw.io/):

f:id:d_tail:20190225115748p:plain

参考記事:
blog.192.works

D - Lazy Faith

問題を読むまでに至らず…

コメント

最近はSolversの多い順に300~400点の過去問を解いていましたが,本格的にアルゴリズムの勉強に立ち向かわないとダメそうです.

【Tumblr API】Tumblrのブログやスキ(like)したポストの写真と動画をダウンロードする【Python】

はじめに

最近,Tumblrがアダルトコンテンツを禁止したり,その判定がガバガバ(キツキツ?)なせいで話題になっていました.

そんなことから,以前API関連を試していた時に,TumblrAPIをいじりかけてそのまま放置していたことを思い出したので,指定したブログや自分がlikeしたポストの写真と動画をダウンロードするコードを試しに書いてみました.

github.com

使用したライブラリ

コードを書くにあたって以下のライブラリを使用しました.

  • pytumblr
  • requests
  • beautifulsoup4
  • tqdm

pytumblrは公式(多分)で提供されている,Tumblr APIを呼び出すためのクライアントを作成できるライブラリです.

使い方

使い方の説明はリポジトリREADMEに書いてありますが,APIキーの取得関連についてだけ参考サイトなどを少し記載しておこうと思います.

このコードを使用するにはAPIキーが必要になります.
まずはアプリケーション登録を行ってコンシューマーキーとシークレットキーを取得します. 以下のサイトなどを参考にすると良さそうです.

また,上のサイトにも記載されているOAuth認証のためのトークンとシークレットトークンも必要になります.
プログラムで認証を行って取得する方法もありますが,以下のサイトから取得するのが簡単そうです.

参考:https://github.com/tumblr/pytumblr

感想

今回使用したライブラリの一つであるBeautifulsoup4ですが,スクレイピング関連で使うということで前から耳にしていたものの,使用するのは今回が初めてでした (大したことには使っていませんが).
スクレイピングもいつかやってみたいと思います.

参考・関連記事

【参加記録】AtCoder Beginner Contest 114

はじめに

AtCoder Beginner Contest 114に参加した記録です.

beta.atcoder.jp

A - 753

入力が7か5か3だったら'YES'を出力,そうでなければ'NO'を出力する.

N = int(input())

if N == 7 or N == 5 or N == 3:
    print('YES')
else:
    print('NO')

B - 754

文字列の先頭から順番に3つずつ取り出し,753との差の絶対値を比べていけば良い.
Pythonだと簡単.

S = list(input())

res = 753

for i in range(len(S)-2):
    X = ''
    for i in S[i:i+3]:
        X += i 
    X = int(X)
    tmp = abs(753-X)
    if tmp < res:
        res = tmp

print(res)

解説では2行で実装していました.

S = input()
print(min(abs(int(S[i:i+3]) - 753) for i in range(len(S) - 2)))

https://img.atcoder.jp/abc114/editorial.pdf

C - 755

(7,5,3)の3桁以上入力の桁数以下の直積集合(?)によって,解説における準七五三数を列挙して条件に合うものの数をカウント.
itertoolsが非常に便利でした.暇があったら使い方のまとめみたいなものを作りたい.
解説によると再帰関数で実装するのが素直な方法らしいです.

import itertools
import collections

N = input()

if int(N) < 100:
    print(0)
    exit()

product_list = []
for i in range(3,len(N)+1):
    product_list += list(itertools.product('753', repeat=i))

res = 0

for i in product_list:
    num = "".join(list(i))
    if int(N) < int(num):
        continue
    if num.count('5') > 0 and num.count('7') > 0 and num.count('3') > 0:
        res += 1

print(res)

D - 756

ググったら解けそうな気がしたけど,時間不足&結局方針も間違えていました.

コメント

ここ最近は競プロにあまり触れていなかったので,C問題が解けるか不安でしたが無事解くことができました.
そして今回のコンテストでレートが緑に到達しました.

f:id:d_tail:20181202235618p:plain

まだまだC問題も安定して解ける訳ではないので,できる限り陥落しないように精進したいです.

【参加記録】AtCoder Beginner Contest 113

はじめに

AtCoder Beginner Contest 113に参加した記録です.

beta.atcoder.jp

A - Discount Fare

X + Y/2を出力すれば良い.
A問題でしたが,制約をちゃんと見ていなかったのは気をつけたいです.

X,Y = map(int,input().split())
print(X + int(Y/2))

B - Palace

T−H[i]*0.006を計算してAとの差の絶対値が最小になるiを求めれば良い.
計算結果をintでキャストしたものを提出してしまったため1WA.
焦りすぎたせいで提出までに少し時間がかかってしまったのも反省点.

N = int(input())
T,A = map(int,input().split())
H = [int(i) for i in input().split()]
 
res = - 1
res_val = 100000
for i in range(N):
    av_temp = T - H[i] * 0.006
    if res_val > abs(av_temp - A):
        res = i
        res_val = abs(av_temp - A)
 
print(res+1)

C - ID

入力のPとYの組み合わせに市の番号を追加したものをソートしたり,県ごとに何回市が存在したかをカウントしていくリストを作成したりして解きました.
解法はそこそこで思いつけましたが,Pythonはリスト関係の処理が遅いらしいため,どのように書くか迷って時間を潰してしまいました.(そもそもappendを多用してるのが悪そう)

N,M = map(int,input().split())
PY = []
tmp = []
cheker = []
res = []
for i in range(M):
    tmp = list(map(int,input().split()))
    tmp.append(i)
    PY.append(list(tmp))
    res.append('')
 
sorted_py = sorted(PY, key=lambda x: x[1])
checker = [0 for i in range(N)]
 
for i in range(M):
    index = sorted_py[i][0]-1
    checker[index] += 1
    res[sorted_py[i][2]] = str(sorted_py[i][0]).zfill(6) + str(checker[sorted_py[i][0]-1]).zfill(6)
 
for i in range(M):
    print(res[i])

D - Number of Amidakuji

手付かず.

コメント

C問題がなんとか解けて良かったです.
次回もC問題が解ければレートが緑になる可能性があるので頑張りたいところです.