Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
AtCoder Beginner Contest 001
解説
AtCoder 株式会社 代表取締役
高橋 直大
コンテストデータ
• こちらより入出力のダウンロードが可能
です
– http://www.chokudai.info/atcoder/ABC001.rar
– 個人サーバーですので、不安定な可能性があ
ります。
A問題概要
• 整数が2つ与えられます。引き算した結果
を求めなさい。
– 整数の値は、0以上2000以下
A問題 解説
• まず、2つの整数を、標準入力から読み取
る
– C言語ならscanf, C++ならcinなど
– 解らない場合は、practiceから各言語の例が参
照できます。
– http://practice.contest.atcod...
B問題概要
• 距離を表す整数が与えられる
• これを、VVという単位に変換する
– これは、距離によって場合分けで決定される
B問題 解説
• 整数を読み込んで、場合分け
– 0.1km未満なら~
– 5km未満なら~
• 解らない場合はif~else節について調べよう!

• 全てm単位に揃えてあげると簡単
C問題 問題概要
• 風程・風向の角度が与えられる
• これを、風力、風向(16方位)に変換しなさ
い
C問題 解説
• やることは、B問題と全く同じ!
– 風程も風向も、場合分けして変換してあげる
だけ!

• でも、if文を大量に書くような実装をして
はいけません!
– 通るけれども、面倒だし、バグも出やすい
C問題 風向きの処理
• 16方位の間隔は全て一定
– 全部のif文を書かずに、繰り返しで処理でき
る!
• 全ての間隔は22.5度間隔なので、22.5度ずつ増やし
て判定する

– もっと簡単に、数式で一発で表すことも可能
• ((Dis *...
C問題 風速の処理
• 風程を60で割ると、風速になる
– この割り算の処理が凄く危険!!

• 例えば、風程201mだと風速3.35m/sだが、
3.35は風力の境界線上
– 誤差で少しでもずれると、間違った判定をし
てしまう。
• 3.34...
C問題 小数の対策方法
• 基準となる風力を、逆に風程に変換する
– 風速3.35m/s以下

→ 風程201m以下

• 少しだけ小さい値を足してあげる
– 3.499999.. + 0.00001
– 3.500000.. + 0.0000...
C問題 風速の処理
• 入力が面倒!
– とりあえずコピペして、数字だけ抽出するよ
うなプログラムをさくっと書こう!
• それが面倒な人は、手入力や1つずつコピペが早
いと思います。
• 英語しか読み込めないテキストエディタで開い
て、?を消去...
D問題 問題概要
• 雨が降った期間が複数与えられる
• マージしなさい
D問題 前処理
• データを丸める
– 1357-1457

→

1355-1500

• やり方
– まず時間と分を、分だけの単位に変換する
• 1時間を60分として、0時0分から何分経ったか、
に変換する

– 5で割った余りに対して、足...
D問題 解説
• それぞれの間隔において、配列を用意し
てあげる

0:00

1:0
0
D問題 解説
• それぞれの間隔において、配列を用意し
てあげる初期値は全て0
• 入力に対して、その範囲を1で塗りつぶす
– 例: 0:20 – 0:45
0:00

1:0
0
D問題 解説
• それぞれの間隔において、配列を用意し
てあげる初期値は全て0
• 入力に対して、その範囲を1で塗りつぶす
– 例: 0:20 – 0:45 の後追加で、0:10 – 0:40
0:00

1:0
0
D問題 解説
• それぞれの間隔において、配列を用意し
てあげる 初期値は全て0
• 入力に対して、その範囲を1で塗りつぶす
– 例: 0:20 – 0:45 の後追加で、0:10 – 0:40

• 左から順番に、連続した範囲を調べる
0:0...
D問題 高速な解法1
• 入力をソートしよう!
D問題 高速な解法1
• 開始時間が早い順にソートする
D問題 高速な解法1
• ソートしてしまえば、順番に処理してあ
げれば、範囲を更新出来る。
– 例えば、10:00 – 11:30の後に、10:30-12:30が来
た場合
• 10:00-12:30に更新する

– その後13:30-14:0...
D問題 高速な解法2
• 座標を圧縮しよう
– 事前に境界線を調べておいて、その範囲しか
調べない!
0:00

1:0
0

0:00

1:0
0
D問題 高速な解法3
• 通称「いもす法」を使おう!
– いままでのやり方
0:00

1:0
0

– いもす法(始点に1、終点の1個先に-1を入れ
る)
0:00

1:0
0
1

-1
D問題 高速な解法3
• 色んな範囲に対して、始点に1を足して、
終点に-1を足す、を繰り返す

0

1

1

1

-1

0

0

-1

-1

0

1

1:0
0
-1
D問題 高速な解法3
• 作った配列に対して、そこまでの足した
値を計算してあげる
– 元の配列
0

1

1

1

-1

0

0

-1

-1

0

1

1:0
0
-1

2

2

2

1

0

0

1

0

– 足...
D問題 高速な解法3
• この配列の、数字が1以上になっている範
囲が、求める範囲
– 入力範囲が増えても、始点と終点だけを入れ
れば良いので、配列すべてをなぞるのは1回
だけで良い!

0

1

2

3

2

2

2

1

0

0...
Upcoming SlideShare
Loading in …5
×

ABC001 解説

11,474 views

Published on

ABC001です

Published in: Technology
  • Be the first to comment

ABC001 解説

  1. 1. AtCoder Beginner Contest 001 解説 AtCoder 株式会社 代表取締役 高橋 直大
  2. 2. コンテストデータ • こちらより入出力のダウンロードが可能 です – http://www.chokudai.info/atcoder/ABC001.rar – 個人サーバーですので、不安定な可能性があ ります。
  3. 3. A問題概要 • 整数が2つ与えられます。引き算した結果 を求めなさい。 – 整数の値は、0以上2000以下
  4. 4. A問題 解説 • まず、2つの整数を、標準入力から読み取 る – C言語ならscanf, C++ならcinなど – 解らない場合は、practiceから各言語の例が参 照できます。 – http://practice.contest.atcoder.jp/tasks/practice_ 1 • 読み取った2つの式を引き算 • 出てきた値を出力する – こちらもわからない場合はpracticeから確認
  5. 5. B問題概要 • 距離を表す整数が与えられる • これを、VVという単位に変換する – これは、距離によって場合分けで決定される
  6. 6. B問題 解説 • 整数を読み込んで、場合分け – 0.1km未満なら~ – 5km未満なら~ • 解らない場合はif~else節について調べよう! • 全てm単位に揃えてあげると簡単
  7. 7. C問題 問題概要 • 風程・風向の角度が与えられる • これを、風力、風向(16方位)に変換しなさ い
  8. 8. C問題 解説 • やることは、B問題と全く同じ! – 風程も風向も、場合分けして変換してあげる だけ! • でも、if文を大量に書くような実装をして はいけません! – 通るけれども、面倒だし、バグも出やすい
  9. 9. C問題 風向きの処理 • 16方位の間隔は全て一定 – 全部のif文を書かずに、繰り返しで処理でき る! • 全ての間隔は22.5度間隔なので、22.5度ずつ増やし て判定する – もっと簡単に、数式で一発で表すことも可能 • ((Dis * 10 + 1125) / 2250) % 16などの処理で、0~15 の数字に変換できる • N,NNEなどの方向を表す文字列は、配列と して書いておく – 問題文からコピーして抽出しても良い
  10. 10. C問題 風速の処理 • 風程を60で割ると、風速になる – この割り算の処理が凄く危険!! • 例えば、風程201mだと風速3.35m/sだが、 3.35は風力の境界線上 – 誤差で少しでもずれると、間違った判定をし てしまう。 • 3.3499999999999….だと、風力2 • 3.3500000000000….だと、風力3
  11. 11. C問題 小数の対策方法 • 基準となる風力を、逆に風程に変換する – 風速3.35m/s以下 → 風程201m以下 • 少しだけ小さい値を足してあげる – 3.499999.. + 0.00001 – 3.500000.. + 0.00001 – どちらも風力3となる • 入力が整数のみだから使える方法なので注意! • 入力間隔が細かいときなどは使えない場合があり ます
  12. 12. C問題 風速の処理 • 入力が面倒! – とりあえずコピペして、数字だけ抽出するよ うなプログラムをさくっと書こう! • それが面倒な人は、手入力や1つずつコピペが早 いと思います。 • 英語しか読み込めないテキストエディタで開い て、?を消去、なんて手もあります – 必要な数字を配列に入れてしまえば、繰り返 し判定するだけ!
  13. 13. D問題 問題概要 • 雨が降った期間が複数与えられる • マージしなさい
  14. 14. D問題 前処理 • データを丸める – 1357-1457 → 1355-1500 • やり方 – まず時間と分を、分だけの単位に変換する • 1時間を60分として、0時0分から何分経ったか、 に変換する – 5で割った余りに対して、足したり引いたりを 行う
  15. 15. D問題 解説 • それぞれの間隔において、配列を用意し てあげる 0:00 1:0 0
  16. 16. D問題 解説 • それぞれの間隔において、配列を用意し てあげる初期値は全て0 • 入力に対して、その範囲を1で塗りつぶす – 例: 0:20 – 0:45 0:00 1:0 0
  17. 17. D問題 解説 • それぞれの間隔において、配列を用意し てあげる初期値は全て0 • 入力に対して、その範囲を1で塗りつぶす – 例: 0:20 – 0:45 の後追加で、0:10 – 0:40 0:00 1:0 0
  18. 18. D問題 解説 • それぞれの間隔において、配列を用意し てあげる 初期値は全て0 • 入力に対して、その範囲を1で塗りつぶす – 例: 0:20 – 0:45 の後追加で、0:10 – 0:40 • 左から順番に、連続した範囲を調べる 0:00 1:0 0
  19. 19. D問題 高速な解法1 • 入力をソートしよう!
  20. 20. D問題 高速な解法1 • 開始時間が早い順にソートする
  21. 21. D問題 高速な解法1 • ソートしてしまえば、順番に処理してあ げれば、範囲を更新出来る。 – 例えば、10:00 – 11:30の後に、10:30-12:30が来 た場合 • 10:00-12:30に更新する – その後13:30-14:00が来た場合 • 10:00-12:30を出力し、13:30-14:00をメモリに入れ る – その後13:40-13:50が来た場合 • 更新する部分がないので何もしない
  22. 22. D問題 高速な解法2 • 座標を圧縮しよう – 事前に境界線を調べておいて、その範囲しか 調べない! 0:00 1:0 0 0:00 1:0 0
  23. 23. D問題 高速な解法3 • 通称「いもす法」を使おう! – いままでのやり方 0:00 1:0 0 – いもす法(始点に1、終点の1個先に-1を入れ る) 0:00 1:0 0 1 -1
  24. 24. D問題 高速な解法3 • 色んな範囲に対して、始点に1を足して、 終点に-1を足す、を繰り返す 0 1 1 1 -1 0 0 -1 -1 0 1 1:0 0 -1
  25. 25. D問題 高速な解法3 • 作った配列に対して、そこまでの足した 値を計算してあげる – 元の配列 0 1 1 1 -1 0 0 -1 -1 0 1 1:0 0 -1 2 2 2 1 0 0 1 0 – 足した配列 0 1 2 3
  26. 26. D問題 高速な解法3 • この配列の、数字が1以上になっている範 囲が、求める範囲 – 入力範囲が増えても、始点と終点だけを入れ れば良いので、配列すべてをなぞるのは1回 だけで良い! 0 1 2 3 2 2 2 1 0 0 1 0

×