130323 slide all

63
2013/03/23合同練習会解説 問題作成、選択:松永 解説、テスター:池谷

Upload: ikea0064

Post on 13-Apr-2017

386 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: 130323 slide all

2013/03/23合同練習会解説

問題作成、選択:松永  解説、テスター:池谷

Page 2: 130323 slide all

問題 アルゴリズム 難易度(国内予選)

A 実装 A

B 実装 A

C シミュレーション A(Small)  /  B(Large)  

D 幾何、場合分け B

E シミュレーション   B

F 幾何、シミュレーション、貪欲 C-­‐

G 横型探索(BFS) C-­‐

H 動的計画法(DP) C-­‐

I バックトラック(DFS) C-­‐

J バックトラック/ビットDP C-­‐  /  C

K 構文解析、再帰 C

L バックトラック C+

総評

Page 3: 130323 slide all

総評その2l 第1回ではやさしい幾何がなかったので、第2回では、入れるようにしたそうです  l チームに1人くらい、できる人がいると頼もしいですね  

l G~Lまでは典型問題なので、わからなかったら復習するといいでしょう  l 復習しないと問題が解けないままだと思います  

Page 4: 130323 slide all

A  温度測定

原案: TopCoder  SRM  310  Div  2  Easy

Page 5: 130323 slide all

問題概要

l  1分間に1度、気温を測定する装置  l 不正確な測定値が存在する  

l 値が-­‐273度未満  l 前後2分以内に計測したすべての値との差が2より大きい  

l 正しい測定値のみの平均気温を求める  l すべて不適切な測定値ならば-­‐300.0を出力  

Page 6: 130323 slide all

解法

1.  i分のときに計測した気温が、適切か不適切かを判断する  

l  Boolean型の配列を用意して、i分のときの計測が正しいかどうかを求める  

2.  適切な計測値だけで平均を求める  l  正しい計測値だけの合計とその個数を求める  l  型変換と0で割ることに注意する  

Page 7: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(Java)50行  l 池谷(Java)51行  

l 提出した数:14  l ACしたチーム数:9  l First  AC時間:18min  

Page 8: 130323 slide all

B  成績調査

原案: Codeforces  152Aを改題

Page 9: 130323 slide all

問題概要

l N人の学生の、m科目の成績がある  l ある科目において、一番高い成績を取った人は「ベストな学生」である  

l  1つでもベストである科目がある学生の人数を求める  

Page 10: 130323 slide all

解法

1.  i番目の学生がベストであるのかどうかを計算する  

1.  まずは2次元配列に入力値を格納  2.  各列(縦)に対して、max値を求める  3.  Max値と同じ値を持つならば、booleanの配列にtrueを格納する  

2.  最終的にその数を数える

Page 11: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)32行(マクロ部分含めず)  l 池谷(Java)38行  

l 提出した数:16  l ACしたチーム数:13  l First  AC時間:4min  

Page 12: 130323 slide all

C  センサー付きロボット

原案:オリジナル

Page 13: 130323 slide all

問題概要

l 2次元平面上に置かれたロボット  l F(直進),  R(右),  L(左)の命令  l 壁があると180度回転する  l ロボットの最後の位置と、初期位置から最も離れた距離の位置を求める  

l (Small):壁の数が4  l (Large):壁の数が4以上100以下  

Page 14: 130323 slide all

考察

l ロボットが距離1しか進まないことと、壁がx軸とy軸に平行であることから、壁にちょうどぶつかる  

l つまり、ロボットが進んだ時に、壁の線分上に位置していれば壁にぶつかったと言える  

l Largeを解くには、壁にぶつかる判定をどのように実装されるかが要求される  

Page 15: 130323 slide all

解法(Small,  Large)l Small,  Large共にシミュレーションしていけばよい  l 現在のx,  y,  方向、を値に持つ変数を用意  l 命令が来たら、移動or回転して、最も離れている位置であるならば、更新  

l 最大距離判定の際に、無理に平方根を取る必要はないです  l √を取らずに比較すれば誤差が怖くないです  

Page 16: 130323 slide all

Small解法l N  =  4なので、長方形or正方形  

l  minX,  minY,  maxX,  maxYを持っておけばよい  

l 壁にぶつかる判定が楽  l  x,y共に、最小値より大きく、最大値より小さければよい  

l 逆に考えて、x,yが最小値または最大値であればfalse、としてもよい

Page 17: 130323 slide all

Large解法l 入力値は0以上100以下なので、その座標が壁であるかどうかの配列を用意する  l  array[y座標][x座標]  =  壁かどうか(true  or  false)  

l それとは別に、壁の座標を記録しておき、進んだときに線上に存在するか、という方法でもできます  

Page 18: 130323 slide all

実装の工夫点とか

l (共通)方向ベクトルを作るといいです  l  int  []  vx  =  {0,1,0,-­‐1};  //上,右,下,左  l  int  []  vy  =  {1,0,-­‐1,0};  l  nextX  =  x  +  vx[dir] って感じで書きます  

l C++だとpair<int,  int>で座標管理できます  

Page 19: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l  (Small)松永(C++)64行  l  (Small)池谷(Java)78行  l  (Large)松永(C++)87行  l  (Large)池谷(Java)90行  

l 提出した数 5(small)/  2(large)  l ACしたチーム数:3  /  2  l First  AC時間:98min  /  99min  

Page 20: 130323 slide all

D  恋人同士の移動時間

原案:  East  Central  North  America  2011  I  :Wally  World

Page 21: 130323 slide all

問題概要

l 平面上の点に2人の恋人がいる  l 通過することができない壁が存在する  

l 壁は線分でx,yのどちらかに平行  

l  1秒間で1m進むことができる  l 2人が合うのに必要な最小の時間を求める

Page 22: 130323 slide all

サンプル解析

l サンプル1 l サンプル2

(5,  2) (7,  2)

1.00000000

(1,  2) (3,  2) (2,  1)

(2,  100)

1.41421356  =  √2

Page 23: 130323 slide all

考察と解法

l 2人の速さが同じなので、2人の最短距離の半分が求めたい時間になる  l 出会う場所は、距離の半分の場所になる  

l 壁がない時は2点の距離が最短距離になる  l 2人の間に壁があるならば、壁の端を通るような経路を考えればよい  l 壁の端点を通る経路は2通り  l  2人の間に壁があるかどうか =>  線分と線分の交差判定  

Page 24: 130323 slide all

線分と線分の交差判定

l ライブラリを公開している人を参考にしてください(割愛します)  

l  Javaならば、  Line2D.intersectsLine()というメソッドがあります  

l ライブラリを持っていなくとも、2点から直線の式を求めて、壁の座標から判定することは可能です  

l 易しい幾何が国内予選で出る可能性はゼロではないので、勉強しましょう  

Page 25: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)61行  l 池谷(Java)39行  

l 提出した数:6  l ACしたチーム数:3  l First  AC時間:87min  

Page 26: 130323 slide all

E  戦艦ゲーム

原案:  GCPC  2012  A:  Battleship

Page 27: 130323 slide all

問題概要

l 2人のプレーヤーが交互に相手の戦艦を撃沈させていく  

l 撃沈させた時、相手の戦艦が残っているならば、自分の順番を続けられる  

l 2番目のプレーヤーは全滅してももう一回のターンができる  

l ゲームの勝敗を求める

Page 28: 130323 slide all

解法

l シミュレーションする  l 事前に残り何体あるのか、を計算する  l 当たっていれば、もう一回自分のターン、ただし残り個数が0ならターン交代  

l 当たっていないならば、ターン交代  l 相手のターン終了時にどちらか一方でも戦艦の個数が0であれば終了する  

l 最後に残り個数を判断して勝敗を計算する  

Page 29: 130323 slide all

実装の工夫点など

l 問題文をしっかりと理解しましょう  l 重要な部分には線を引いたり、要約した紙を作るといいでしょう  

l 3次元配列で図の状態を持つと楽かもです  l  Field[0:  自分,  1:相手][h][w]といった具合  

l シミュレーション問題は、ある程度紙にまとめてから書いた方がいいと思います  l コーディングしてから失敗に気づく、というのは、結構なロスだと思われます  

Page 30: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)78行  l 池谷(Java)79行  

l 提出した数:13  l ACしたチーム数:3  l First  AC時間:78min  

Page 31: 130323 slide all

F  頑固なヌーRick

原案:  Asia  Taiwan  2004

Page 32: 130323 slide all

問題概要

l ヌーが牧草地に向かって移動を繰り返す  l 距離D以内で移動しないといけない  l FSの方向に最も近い方向の場所を選ぶ  

l 最低限FSの方向に直角未満で進まないとダメ  

l 方向を変える角度が直角以内でないとダメ  

l ヌーが移動した経路を求める  

Page 33: 130323 slide all

解法

l 経路はただ一つに決まるので、素直にシミュレーションをしていけばよい  

l 満たさないといけない条件  l 距離D以内  l  FSの方向に90度以内  l 直前の方向と90度以内  

l 最もFSの角度が小さいものを選べばよい  l 角度の計算方法が分かればできる  

Page 34: 130323 slide all

角度の計算

l 内積の公式より、 l v1・v2=|v1||v2|cosθ  から式変形して、  l   θ=arccos(v1・v2  /  (|v1||v2|))  

l C++では、complex型のarg関数で角度計算できるようです  

Page 35: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)73行  l 池谷(Java)83行  

l 提出した数:1  l ACしたチーム数:1  l First  AC時間:198min  

Page 36: 130323 slide all

G  エレベータの故障

原案:  NCPC  2011  D  Elevator  Trouble

Page 37: 130323 slide all

問題概要

l エレベーターに乗って、s階からg階に行く  l エレベーターは、上にu階、または、下にd階移動できる  

l ボタンを押す最小回数を求める  l 無理ならば、”use  the  stairs”を出力する

Page 38: 130323 slide all

解法

l 横型探索をします  l 現在の位置と何回ボタンを押したのか、を状態として持って、状態をキューで管理する  

l キューがなくなるまで、キューから状態を取得して、新たな状態をキューに入れるという操作を繰り返す  

l 重複した状態は、キューに入れる必要なし  

l コードを見た方がわかりやすいと思います  

Page 39: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)52行  l 池谷(Java)64行  

l 提出した数:13  l ACしたチーム数:6  l First  AC時間:56min  

Page 40: 130323 slide all

H  良い連立政権

原案:  BAPC  2012  G:  Good  Coalision

Page 41: 130323 slide all

問題概要

l n個の政党があり、政党ごとに、獲得した議席数と任期を満了できる確率が与えられる  

l 政党を連立させ、過半数(=76以上)となるときの最大の任期満了率を求める  l 連立させると、議席数は加算され、確率は掛け算となる

Page 42: 130323 slide all

解法

l 動的計画法  l dp[i番目までの政党][議席数]  =  確率  l 初期値はdp[0][0]  =  100.0  l その政党を使うor使わないの2通りの遷移  

l 使うなら議席数を加算して、確率を乗算  l 使わないなら議席数、確率はそのままで遷移  

l 最終的に議席数が76以上のiにおける、dp[n][i]の最大値を求めればよい  

Page 43: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)42行  l 池谷(Java)39行  

l 提出した数:4  l ACしたチーム数:3  l First  AC時間:147min  

Page 44: 130323 slide all

I  彫像

原案: Codeforces  #94  Div2  C:  Statues

Page 45: 130323 slide all

問題概要

l 8×8のチェス盤がある  l 左下にいるMariaが右上に到達したい  l Mariaの移動は8近傍。彫像のマスには不可  l 彫像はMariaが移動していると同時に1マス下に移動する。一番下のときは消える  

l 現在Mariaのマスにいると彫像の勝ち  l 右上に進んだらMariaの勝ち  l 勝敗を求めよ  

Page 46: 130323 slide all

解法

l 右上にたどり着ければもちろん勝ち  l また、8ターン生き延びれたらMariaの勝ちは必然となる  l 彫像は長くても8ターンで消えてしまう  l 実質は7ターン目でも大丈夫だと思われる  

l つまり、バックトラックをして、右上にたどり着けるor深さ8の所までたどり着ければ勝ちとなる  

Page 47: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)84行  l 池谷(Java)76行  

l 提出した数:6  l ACしたチーム数:1  l First  AC時間:109min  

Page 48: 130323 slide all

J  アレルギーテスト

原案:  NCPC  2009  C  Allergic  Test

Page 49: 130323 slide all

問題概要

l K個のアレルゲンが与えられる  l アレルゲンはD日間活性している  l 一日に最大1つアレルゲンを与えることができる  

l ある日にちのときに、アレルゲンが2つ以上活性化していると検査できない  

l テスト計画を実施する最短の日時を求める

Page 50: 130323 slide all

サンプル解析

l  k  =  3,  {2,  2,  2}   l  k  =  5,  {1,4,2,5,2}

答えは5

各アレルゲンごとに  最低一日は、単体のテストの  日にちを作らないといけない

答えは10

Page 51: 130323 slide all

Small解法l バックトラックをして、並び順を全探索する  

l 使ってないものを一つ選んで、使ってるものの右側に追加するようなイメージ  

l 現在の深さ、次のテストは何日から始めればよいか、現在の合計を引数をして再帰していけばよいです  

l 計算量はk!  =  9!  =  10^5くらい  l  LargeだとTLEとなってしまう

Page 52: 130323 slide all

Large解法l bitDP[使った集合][重複してもよい日数]  

l 使った集合に対して、重複してもよい日数がxのときの最小の日数を求めていく  

l 初期状態は0、最終的な状態は(1  <<  k)  -­‐  1  l いわゆる「渡す(飛ばす)DP」で書いた方がわかりやすいと思います  

l 計算量はO(k  *  8  *  2  ^  k)  =  10^  8くらい  

Page 53: 130323 slide all

ちょっと高度なお話

l 最小日数が同じ場合であれば、重複してもよい日数が多い方がよいです  l 使った集合に対して、最小の日数と、最大の重複してもよい日数を持っているだけでよい  

l 計算量はO(k  *  2  ^  k)  =  10^  7  

重複日数3 重複日数0

Page 54: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l  (Small)池谷(Java)44行  l  (Large)松永(C++)55行  l  (Large)池谷(Java)58行  

l 提出した数:2(small)/0(large)  l ACしたチーム数:0/0  l First  AC時間:-­‐-­‐/-­‐-­‐  

Page 55: 130323 slide all

K  等式

原案:オリジナル

Page 56: 130323 slide all

問題概要

l x,y,zの3つの変数を含む式がある。  l 式は足し算と掛け算のみ  l 右辺は整数  

l 式が成立するような変数の組み合わせは何通りあるか求める  

Page 57: 130323 slide all

解法

l x,y,zについて1~100までループを回して、構文解析をする  

l 掛け算が省略されているので、掛け算の記号を追加して構文解析するといいと思います  

l 構文解析の入門的問題はAOJ0109です

Page 58: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)124行  l 池谷(Java)141行  

l 提出した数:3  l ACしたチーム数:3  l First  AC時間:128min  

Page 59: 130323 slide all

L  平面上の蛇

原案:  East  Central  North  America  2006  G:  Snakes  on  a  Plane

Page 60: 130323 slide all

問題概要

l n  *  mのグリッドがある  l 蛇を構成する四角形は1を表す  l 蛇は4方向で2つ、1の正方形と接している  

l 蛇の頭としっぽは例外  

l 最大蛇は、0の正方形を1に変換しても、蛇の長さが変わらない蛇のことである  

l 最大蛇の数を求めよ  

Page 61: 130323 slide all

解法

l 最大蛇でない時の判定  l 蛇の頭またはしっぽのまわりに1を追加する  l 追加したマスの周りに、1のマスが1個しかない時、長さが長くできる  

l  1のマスの次数が3つ以上1のマスであるとき、蛇ではないので、それも除外する  

l 最大蛇でないと確定できたら、違う色に塗りつぶすなどすればいいでしょう  

Page 62: 130323 slide all

ジャッジ解と提出状況

l ジャッジ解  l 松永(C++)134行  l 池谷(Java)93行  

l 提出した数:5  l ACしたチーム数:0  l First  AC時間:-­‐-­‐  

Page 63: 130323 slide all

お疲れさまでした