Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Chargement dans…3
×
1 sur 9

mod7占い【上級・アルゴリズム】解説

2

Partager

Télécharger pour lire hors ligne

mod7占い【上級・アルゴリズム】解説

Livres associés

Gratuit avec un essai de 30 jours de Scribd

Tout voir

mod7占い【上級・アルゴリズム】解説

  1. 1. 029_mod7占い【上級・ アルゴリズム】解説 ギノ株式会社 吉岡 恒夫
  2. 2. 問題 • 問題: https://paiza.jp/learning/mod7 • あなたは今、「mod7占い」というサービスを始めようと考えています。 • mod7占いとは、整数が書かれた複数のカードの中から3枚を選び、そこ に書かれた整数の和が7で割り切れるかどうかで運勢を決めようというも のです。 カードは必ず異なる3枚を選ぶ必要があり、全てのカードには全 て異なる数字が書かれています。 • 占いというからには、7で割り切れる組み合わせはそれなりに少なくする 必要があります。 そこで、適当な複数のカードに対して、カードに書か れた3つの整数を足した和が7で割り切れるような組合せがいくつあるか を計算するプログラムを作成してください。
  3. 3. 問題まとめ • N個の数列a_iから3つを選ぶ • 3つの数字の合計が7で割り切れる組み合わせの 数を出力する。 • 1≤N≤100,000 0≤a_i < 2^32
  4. 4. 解法1 (総当たり) • 1つ目の数字を選ぶループ • 2つ目の数字を選ぶループ • 3つ目の数字を選ぶループ • 合計が7で割り切れるか確認
  5. 5. 解法1(計算量) • 三重ループ • 組み合わせの数: C(N, 3) = N*(N-1)*(N-2)/6 = 166,661,666,700,000 (n=100,000) • 計算量: O(N^3) • 無理~
  6. 6. 解法2 • 足す前に剰余を取っても、結果は変わらない。 (A+B)%7 = (A%7 + B%7 + C%7)%7 • 0~6の値のみ与えられたと考えてよい。 • 3つを選ぶ組み合わせは 7 * 7 * 7 = 343
  7. 7. 解法2 • 各a_iについて、7で割った余り0-6の出現回数を数える。 • 0-6の数字から1つめの数字を選ぶループ • 0-6の数字から2つめの数字を選ぶループ • 0-6の数字から3つめの数字を選ぶループ • 組み合わせの数を計算 1つめの数、2つめの数、3つめの数、 の出現回数を掛け合わせる 2つの数字が同じ場合、重複を除くため重複の片方を1引いて、2で割 る 3つの数字が同じ場合、重複を除くため重複の片方を1もう片方を2引 いて、6で割る
  8. 8. コード
  9. 9. N= gets.to_i counts = Array.new(7,0) STDIN.read.split.map(&:to_i).map{|i| i%7}.each{|a| counts[a] += 1 } total = 0 (0..6).each{|i| (i..6).each{|j| (j..6).each{|k| next if (i+j+k)%7 != 0 c1 = counts[i] c2 = counts[j] c3 = counts[k] c2 -­‐= 1 if i == j c3 -­‐= 1 if k == i c3 -­‐= 1 if k == j pat = c1*c2*c3 if i==j && j==k pat /= 6 elsif i==j || i==k || j==k pat /= 2 end total += pat } } } puts total

×