ABC011は不参加。
最近のABCの中では若干難易度低目。
http://abc011.contest.atcoder.jp/assignments
A - 来月は何月?
与えられた翌月が何月か答える。
12月の時だけ翌月を1月と答えればよい。
import sys N=input()+1 if N>12: N-=12 print N
B - 名前の確認
文字列が与えられるので、先頭を大文字に、それ以外を小文字にする。
Pythonはupper/lower関数があるので楽だね。
import sys S=raw_input().strip().lower() print S[0].upper() + S[1:]
C - 123引き算
Nが与えられるので、最大100回、1か2か3を引いて0に出来るか。
ただしNG値3つを経由してはならない。
NG値にならない範囲で、出来るだけ多くの数値を引き、100回後に0になっていればok。
import sys N=input() NG1=input() NG2=input() NG3=input() if N==NG1 or N==NG2 or N==NG3: print "NO" sys.exit(0) for i in range(0,100): j=min(3,N) while j>0 and (N-j==NG1 or N-j==NG2 or N-j==NG3): j-=1 N-=j if N==0: print "YES" else: print "NO"
D - 大ジャンプ
初期状態で座標(X,Y)にいる。
上下左右のいずれかの方向に1/4の確率で長さDだけ移動、をN回繰り返したとき、原点に戻る確率を求めよ。
まず、X,YがDで割り切れない場合はそもそも原点にたどり着けない。
それ以外の場合、原点に戻る上下左右の移動回数u,d,l,rの条件は以下のように3つの式で表現できる。
- u+d+l+r = N
- l-r = X/D
- d-u = Y/D
4変数で3式なので、1個変数を決め打ちすれば他の3つの値も決まる。
そこで1変数を総当たりすればよい。
上下左右の移動回数が決まると、その発生確率は以下の通りなので、これらを足し合わせればよい。
なお、普通に上記式を計算するとNが大きい場合特に4^(-N)の計算結果の桁が小さすぎてdoubleにも収まらなくなる。
以下の方法では、Combinationの前計算の時点でCが小さくなるようにしておき、最後の4^(-N)の部分がここまで精度が落ちないようにしている。
import sys import math C = [[0 for j in range(1002)] for i in range(1002)] C[0][0]=1.0 for i in range(0,1001): for j in range(0,1001): C[i+1][j] += C[i][j]/2.0 C[i+1][j+1] += C[i][j]/2.0 N,D=map(int,raw_input().split(' ')) X,Y=map(abs,map(int,raw_input().split(' '))) xp = X/D yp = Y/D if (xp+yp)%2 != N%2 or X%D>0 or Y%D>0: print 0.0 sys.exit() ret = 0.0 for x1 in range(0,N+1): x2 = x1-xp y1 = yp+(N-x1-x2-yp)/2 y2 = (N-x1-x2-yp)/2 if x2<0 or y1<0 or y2<0: continue ret += C[N][x1]*C[N-x1][x2]*C[N-x1-x2][y1]*pow(0.5,2*N-(N+N-x1+N-x1-x2)) print ret
まとめ
Dは解き方はさほどでもないけど、精度の問題が若干厄介だったね。