水面下の夢

競プロやイラストに興味があります.メインブログがここ.同人サークル「かのらぶ」のページはこっち( https://yumechi0525.amebaownd.com ).ブログアイコンはYaQ(@8_9_00)さんから.

No.221 犯罪都市, No.222 引き算と足し算(2015/06/05)

久々にyukicoderに参加(久々?)
今回は開始時点から参加できたので,19位と過去最高の順位でした(あれ? 夜見た時にはもう少し下だと思ったのですが)



No.221 犯罪都市

解答

#30900 No.221 犯罪都市 - yukicoder

問題文がわかりにくいみたいな話が上がってましたね.
99%の確率でマフィアを判定できる機械がある.10000人の中にN人のマフィアがいる.この時,誤認逮捕率を求めよ.
誤認逮捕なので,マフィアでない一般の人がどれくらい間違えて逮捕されるのかを考えれば良い.

なので,計算式は以下の式で求められる.

間違えて捕まえてしまう一般の人 / (逃してしまうマフィアの人数 + 間違えて捕まえてしまう一般の人)

Pythonのコードにするとこのようになる.*1

((10000 - N) * 0.01 / (N * 0.99 + (10000 - N) * 0.01))

上記のものを100倍して出力すればおしまい.

N = int(input())
print(100 * ((10000 - N) * 0.01 / (N * 0.99 + (10000 - N) * 0.01)))

No.222 引き算と足し算

回答

#30964 No.222 引き算と足し算 - yukicoder

アリスちゃんは足し算と引き算を逆に認識してるからアリス基準で計算してってさ!
というわけで,ちょっとひねったA+Bみたいな….

解決方針は様々でしょうが,私は地道にときました.

  1. Aに"+", "-"があれば,符号を覚える(実際はマイナスだけ)
  2. Aの数値を切り出す.
  3. 演算子を取り出して,"+"なら"-","-"なら"+"で保持.
  4. Bに"+", "-"があれば,符号を覚える(実際はマイナスだけ)
  5. Bの数値を切り出す.

1,2と4,5は多分統合できるのですが,面倒臭かったのでそのままコピペして変数名だけ変更.
この方針で行けば,この問題は解けます(最適な解とは言えませんが…)
変数が増えても,A,Bの処理の部分をメソッド化して繰り返し適応すればなんとかなるんじゃないかな?

実際の提出コードにはコメントを書きませんでしたが,わかりやすくなることを期待して,コメントを書いておきます.

s = list(input())
a, b = 0, 0

op = ""

# A の記号処理
minus = False
if s[0] == "-":
    minus = True
    s.pop(0)
if s[0] == "+":
    s.pop(0)

# A を切り出す
idx = 0
while s[idx].isdigit():
    idx += 1
num = int("".join(s[:idx]))
s = s[idx:]
a = num if not minus else -num

# 演算子の処理
op = s[0]
if op == "+":
    op = "-"
else:
    op = "+"
s.pop(0)

# Bの記号処理
minus = False
if s[0] == "-":
    minus = True
    s.pop(0)
if s[0] == "+":
    s.pop(0)

# Bを切り出す
idx = 0
while idx < len(s) and s[idx].isdigit():
    idx += 1
num = int("".join(s[:idx]))
b = num if not minus else -num

# 出力
print(a-b if op == "-" else a+b)

*1: マフィアがN人なので,一般の人は10000-Nなのは大丈夫ですよね?