質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1735閲覧

Atcoder A問題

nnnyu16

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2017/07/10 09:37

問題
http://agc017.contest.atcoder.jp/tasks/agc017_a
を以下のように
入力された配列の偶数と奇数の個数を調べ
計算量を減らすため階乗の配列をとってから
コンビネーションを計算し答えを出しました。

ほとんど通るのですが
一部のサンプルでWAとなってしまして、試行錯誤しましたがどこが間違っているのかわかりません。
ご指摘いただけるとうれしいです。
よろしくお願いします。

python

1n, p = (int(i) for i in input().split()) 2A=[int(i) for i in input().split()] 3an=0 4 5for i in range(0,n): 6 A[i]=A[i]%2 7one=A.count(1) 8zero=A.count(0) 9 10f=[1] 11t=1 12for i in range(1,max(one,zero)+3): 13 t=t*i 14 f.append(t) 15#0 16if p==0: 17 if zero!=0: 18 for i in range(0,zero+1): 19 an+=round(f[zero]/(f[zero-i]*f[i])) 20 21 j=0 22 if one!=0: 23 while j<=one: 24 an+=round(f[one]/round(f[one-j]*f[j])) 25 j+=2 26 if one!=0 and zero!=0: 27 an-=1 28#1 29if p==1: 30 oo=0 31 for i in range(0,zero+1): 32 oo+=round(f[zero]/round(f[zero-i]*f[i])) 33 j=1 34 ll=0 35 if one!=0: 36 while j<=one: 37 ll+=round(f[one]/round(f[one-j]*f[j])) 38 j+=2 39 an=oo*ll 40 41print(an)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_Victorique__

2017/07/10 09:46

これはどういう方針でどう解こうとしているのですか?他人から見たら読む気にならないですよこれ。
nnnyu16

2017/07/10 11:00

おっしゃる通りですね。すみません。質問を書き直します。
guest

回答2

0

ベストアンサー

結論から言うと、考え方自体が間違っています。コンビネーションなど出てきませんし、階乗も出てきません。それと、コンビネーションについて、途中計算が浮動少数点数になるような計算をした場合、誤差によって正確にならない場合があります。


偶数と奇数にわけて考えると言うこと自体はいいところです。

###偶数と奇数の性質

問題文を言い換えると、選んだ袋の数の合計について、2で割った余りが0または1になる組合せの数を求める事になります。つまり、合計が偶数か奇数になると言うことです。ここで偶数と奇数の性質について考えます。

  1. 偶数同士をいくら足し合わせても偶数になる。
  2. 奇数同士を偶数回足し合わせると偶数、奇数回足し合わせると奇数になる。
  3. 偶数と奇数を足し合わせると偶数になる。

###全てが偶数の場合

ここで、全てが偶数であると仮定しましょう。性質1.よりどんな組合せであっても合計は偶数になります。つまり、奇数になることはありません。Pが1、つまり奇数になる場合を求める場合は0で固定です。奇数になる組合せがないからです。ではPが0、つまり偶数になる場合はどうでしょう。この場合は、袋をどのように選んでも良いとなるため、一つ一つの袋について選ぶ・選ばないの二択をしていくことです。1番目は選ぶ・選ばないの2通りです。2番目も2通りです。3番目、4番目、、、とずっと2通りの選択です。それぞれの選択は独立しているので、単純に掛け合わせるだけです。つまり、222*...*2と袋の数だけ2を掛けること、いってみれば2の冪乗を求める事になります。袋の数をN個とすると2のN乗、Pythonで書けば2**Nとなります。

よって、全てが偶数であれば、P==0では2**NP==1では0となります。

###奇数が含まれている場合

次に、一つ以上の奇数が含まれている場合を考えましょう。最初の奇数になる袋だけ除外して考えます。残りのN-1個の袋について、奇数になる組合せをFo(N-1)、偶数になる組合せをFe(N-1)とします。P==0になるのは、奇数の袋を選んで奇数になる組合せ(Fo(N-1))になったときと選ばずに偶数の組合せになったとき(Fe(N-1))です。つまり、Fo(N-1)とFe(N-1)は被りませんので、あわせてFo(N-1)+Fe(N-1)です。さて、N-1個の組合せは奇数パターンと偶数パターンの二つだけですので、その合計は全ての組合せの数、つまり2**(N-1)です。つまり、2**(N-1)がその組合せの数になります。P==1の時も全く同じように考えることができるので、その組合せは同じく2**(N-1)となります。

###まとめ

つまり、「奇数が無い(全てが偶数)の場合」と「奇数がある場合」にわけること。「偶数を求める場合」と「奇数を求める場合」にわけること。この四つの場合分けによって、02**(N-1)2**Nのいずれかになると言うことです。あとは、これをコードにしてしまえば終わりです。Pythonには冪乗演算子があるので、とっても簡単ですね。


どうしてもわからないときだけ見てください。
参考: 私が書いた解答例

投稿2017/07/10 11:34

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnnyu16

2017/07/10 15:08

自分で考えてずっとできなかったものが、やっと理解出来ました。 丁寧な解説でとてもわかりやすく助かりました。 ありがとうございました。
guest

0

訂正:

AtCoderのサイトをもういちどよくみてみました。コンテスト中の問題とコンテスト予定の問題がトップページに明記されていますね。それをちょこっと見ればすぐにコンテスト中の問題でないことがわかるということを自分が知らなかっただけのようです。

失礼しました。

元の回答

回答ではなく、この手の質問に対する意見です。

AtCoderって実力を試すサイトなんじゃないですか?
コンテスト中はネタバレ禁止とも書いてありますし、そういう意味では「回答者が一々神経を使わなくていいように質問を遠慮する」のがマナーではないのかなぁと自分には思えます。

解けなければ自分で解けるまで頑張るべきではないですか?

勉強のために問題を解くならこうしたサイトではなくもっと別の場にある問題を解けばいいと思います。
わざわざ実力を測るサイトの問題をもってきてこうした場所で質問するのはどうかと思います。

投稿2017/07/10 10:09

編集2017/07/10 10:46
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/07/10 10:29

すでにコンテストが終わっている問題ですよ。質問もコンテストが終わってからしていますし、一体何が問題なのでしょうか?
KSwordOfHaste

2017/07/10 10:39 編集

そうでしたか。質問者さんには悪かったかも知れませんが、回答者側が神経をつかうのもなぁと感じたので、「コンテスト終わってる問題」と言ってもらえると助かると思いました。AtCoderのサイトをみると「終わっている問題」ということはすぐわかるのかも知れませんね。も一回見てみます。
KSwordOfHaste

2017/07/10 10:49

コンテストが終わっているというのはトップページからでも簡単に確認できることがわかりました。失礼しました。 ご指摘ありがとうございました。>raccyさん
nnnyu16

2017/07/10 10:57

明記すべきでしたね、すみません。 次回からそのあたりにも気を使うようこころがけます。
KSwordOfHaste

2017/07/10 11:35

いえ、問題が非公開で純粋に実力を測るサイトのものとAtCoderのようなものをごっちゃにしてしまった自分が物をしらなかったということでした。大変失礼しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問