Upload
-
View
169
Download
0
Embed Size (px)
Citation preview
HAPPY NEW YEAR 2017 コンテスト
解説
作問者• 1,2,3,4,5,8,9,10,12→@sujinbemani_79c
• 7,11→@TSUYOSSHI_
• 6→@suzukze_hunachi
1.歌舞伎とかの幕
問題概要• 左から順番に緑→オレンジ→黒を繰り返す
• 左からx列目は何色?
• 緑→1 オレンジ→2 黒→3を出力
• xは10^18以下
1.歌舞伎とかの幕
解法(150点)• 3で割った余りを使う
• 規則正しく変わってる みたいな問題は余りを取るとよい
1.歌舞伎とかの幕
注意点• 3で割った余りが0の時、3を出力する
• int型ではおさまらない(部分点の100点は取れる)
→long long intなどを使おう
2.漫画の整理
問題概要• 幅がx[cm]の棚に本を入れるだけ入れる
• 本を入れる順番は決まっている
• 入らなくなったら棚をもう一個用意する
• 棚は何個要るか
• 本の冊数Nは10^5以下
• 棚の幅より幅を取る本はない
• 棚と本の幅の大きさはどちらも10^9以下
2.漫画の整理
解法(150点)• シミュレーションやるだけ
• やるだけとは言っても若干頭がこんがらがる
• ゆっくり考えたり紙に書いて考えたりしよう
2.漫画の整理
ソースコード例int N,x;
cin>>N>>x;
int ans=1;
int now=0;
for(int i=0;i<N;i++){
int a;
cin>>a;
now+=a;
if(x<now){
ans++;
now=a;
}
}
cout<<ans<<endl;
3.P君(弟)の冒険
問題概要• 毎秒左右のどちらかのマスに動く
• x秒後に居る可能性のあるマスの数は?
• xは10^9以下
3.P君(弟)の冒険
部分点解法(15点)• x=1
• テストケースにx=1のケースあるよ^^
• というか1の場合答えが2になることくらい、人力でわかる
3.P君(弟)の冒険
部分点解法(120点)• x≦10
• BFS(深さ優先探索)、DFS(幅優先探索)などで全通り試そう
• 一番頭悪い方法でO((2^x)*x)、頭良い方法でO(x^2)
3.P君(弟)の冒険
解法(150点)• x+1が答え
• 正確な証明方法もあるが、何個か自分でやってみて察するほうが速い
• テストケースで1→2と4→5となっているのとテストケースの図から察そう
4.P君(兄)の冒険
問題概要• 毎秒上下左右のどちらかのマスに動く
• x秒後に居る可能性のあるマスの数は?
• xは2*10^9以下
• さっきの問題の移動方向が上下左右になったもの
4.P君(兄)の冒険
部分点解法(15点)• x=1
• 1の場合答えが4になることくらい、人力でわかる
4.P君(兄)の冒険
部分点解法(120点)• x≦10
• BFS(深さ優先探索)、DFS(幅優先探索)などで全通り試そう
• 一番頭悪い方法でO((4^x)*x)、頭良い方法で(x^2)
4.P君(兄)の冒険
部分点解法(135点)• x≦10^4
• 規則的な模様になるのは自明(テストケースに図もありますし)
• 内側から足すなどして
4.P君(兄)の冒険
解法(150点)• (x+1)^2が答え
• 正確な証明方法もあるが、何個か自分でやってみて察するほうが速い
• テストケースで0→1と3→16となっているのとテストケースの図から察そう
4.P君(兄)の冒険
解法(150点)(の余談)
• 45°傾けてみると?
→可能性のあるマスが正方形に並ぶ
→一辺の長さはx+1
5.大きい is めでたい
問題概要• N個の一桁の非負整数が並んでいる
• 全ての数字の間に+と*を入れて、できるだけ答えを大きくしよう
• ただし掛け算から優先して計算することなく、左から計算する
• N≦10^6
5.大きい is めでたい
部分点解法(100点)• N≦10
• +*を入れる全通りをためす→O(2^N)
• +を入れた時と*を入れた時の計算結果を毎項比較し、大きいほうを取る→O(N)
5.大きい is めでたい
解法(150点)• +を入れた時と*を入れた時の計算結果を毎項比較し、大きいほうを
取る→O(N) ではダメ
• 途中でlong long intの範囲を超えてしまう場合がある
5.大きい is めでたい
解法(150点)• 次の項が0だったら+そうでなかったら* は惜しい
• 次の項が0か1だったら+そうでなかったら* はもっと惜しい
• 今まで計算してきた値が0か1の場合も+ これは正解
• まとめると、
• if(今まで計算してきた値≦1||次の項≦1)puts(“+”);
• else puts(“*”);
6.昼夜逆転
• 次ページから解説始まります
• (ふなちさんのスライドをくっつけたもの)
問題概要
右のような栄養素と元気がわかっている食べ物がありますその中から栄養素を全部とらずに一番元気が得られるように食べ物を選べっていう問題です
これからの解説は右の食べ物の問題設定でいくのでよく覚えちょくれさい😓
部分点解(10点)
• ひたすら全探索
• 全部の要素を使ってない組み合わせのうちで最も元気が得られたときの元気を出力
• これで多分でO(nΣ(k=1)MCk)となるので10点
• でもこれだとMの制約が大きいとすぐTLE
満点解法(200点)
• 累積和を使おうo(^-^)o
• どうやって?
(これは嘘解法です)
• 栄養素でしたの青い部分みたいな感じで累積和をする.
このやり方だと答えが水色の元気が1000の食べ物を食べない事になり、Ans=30+400+100+300=830となり明らかに答えは求められてない
だってそれなら1000だけたべたがええやん!!
では,なにを累積和すればよいのか?
満点解法(200点)
• 栄養素の範囲に元気を足す累積和をしよう.
一番小さい400を元気全部の合計から引いたものが答えとなります😪
Ans=1830-400=1430.詳しくいうと食べない栄
養素を決めるやり方です.このやり方だとO(K+M)
で200点です
おわりw
ではなく、おまけ!!
• 実は数学的な問題を作っていた
• あまりにも典型^プログラミング要素0だった
• ボツw
問題概要• 三角形DEFの面積を求めよ
• c,bに加え頂点Bの角度をB°頂点Aの角度をA°と定義する
• 同じマークのところは等しい角度と定義する
解き方知りたいっていう人はふなちに直接聞いてください😉
• めんどくさがりなのでここで説明はしません。
• ちなみに高校一年生異常なら誰でも解けます。
• さっきの図書くのすごい大変だったから誉めて
7.新年ゲーム
• 次ページから解説始まります
• (つよっしーのスライドをくっつけたもの)
7.新年ゲーム
AOJにある「カードの並び換え」と一緒で全探索します。
だいたいどんなことしても通るけど個人的にはbitを使ってほしかった。
bitを使うとカードを選んだかどうかを楽に管理できるよ!
階乗オーダーなので計算量はO(nPk)です。
7.新年ゲーム
・bitの使い方
ここでいうbitは二進数のことです。
この問題ではカードをbitに見立てます。
例えばカードが三枚のとき最初はbit=111ですね。
次に1枚目のカードを選んだとするとbit=110とすることで
現在残ってるカードを管理できる!!!
このときbitからは1を引いてます。
つまりn番目のカードを選 んだときはbitから2^nを引けばいいよ。
8.かまぼこ
問題概要• 半円筒状の物体を、xy平面、yz平面、zx平面、のいずれかに平行な
平面でN回分ける
• 最大で何個に分離できるか
• N≦10^6
8.かまぼこ
解法(200点)• まず入力にあるrは自明に関係ない
• つぎにかまぼこは凸な立体であるため、直方体と同じと考えてよい
8.かまぼこ
解法• xy平面で切った回数をa、yz平面で切った回数をb、zx平面で切った
回数をcとすると、(a+1)*(b+1)*(c+1)個に分離できる
• a+b+c=Nを満たしながら、(a+1)*(b+1)*(c+1)を最大化すると考えればよい
• a+1をA、b+1をB、c+1をCと置くと、A+B+C=N+3を満たしながら、A*B*Cを最大化すると考えればよい
• 拡張された相加相乗平均の定理より、A、B、Cのどの二つの組の差も1以下にするのが最適だと分かる
8.かまぼこ
解法• ていうかa,b,cの数の差をできるだけ小さくしたほうがいいことくら
い証明しなくてもわかると思うんだけどどうなん?
• 僕はこの問題思いつくときそうしたほうがよさそうってなった後に証明した
9.困ったテトリス
問題概要• テトリス
• ピースの回転と移動はできない
• 横一列にそろっても消えない
• ピースの降らせる順番を自由に変えて、一番高くピースが積もっている部分を低くせよ
• ピース数N≦15
• フィールドの横幅W≦10
9.困ったテトリス
部分点解法(100点)• N≦10
• ピースを振らせる順番を全通り試そう
• O(10!*重めの定数倍)
9.困ったテトリス
解法(200点)• ピースを振らせる順番を全通り試す時、なにが無駄になっているか
→今まで落としたピースが同じで、最上段の形も同じという状態は
一緒の状態とみなせる
• 今まで降らせらたピースをbitで管理
• 最上段の形もbitで管理
9.困ったテトリス
解法(200点)• dp[i][j]はピースを振らせた状態がiで最上段の形がjの時の(最も低い)
低さ
• 配るDPをするとします。dp[i][j]からピースkを置くときに行う配る処理は、
最上段の形と次に降らせようとするピースkをAND演算をした時、
→重なりがある(1以上の値になる)時は、
fie[i+(1<<k)][piece[k]]=min(fie[i+(1<<k)][piece[k]],fie[i][j]+1);
→そうでなければ、
fie[i+(1<<k)][j|piece[k]]=min(fie[i+(1<<k)][j|piece[k]],fie[i][j]);
9.困ったテトリス
解法(200点)• 全ての状態に対して、次のピースを全てのピースを置くことを仮定
するので、O(2^W*2^N*N)=5*10^8でやばい感じがする
• 実際はそんなことない(その状態に行きつかない場合N回の仮定を試行する必要がない)
• ほぼO(2^W*2^N)=3*10^7程度でおさまる(制限時間2秒、定数倍軽めなので間に合う)
9.困ったテトリス
注意点• メモリ量がやばいのでdpの配列はshort intなどを使いましょう
• 最初にdp[0][0]=0としても、答えから-1しなければなりません
• それが気持ち悪い場合はdp[0][(1<<W)-1]=0としましょう
• (最初の状態の最上段の状態は、空ではなくすべて埋まっていると考える)
9.困ったテトリス
別解法• こんなやばそうな配列取る解法気持ち悪いわ!
• もちろんこんな配列取らなくても解く方法はあります。
• というか多分枝狩りとか焼きなましでも通ります。• って解説に書いてたら本当に焼きなましで通してる人がいましたね。
10.数え上げお兄さん
問題概要• H×Wのフィールドにカードが置いてあったり置いてなかったりする
• カードのふちを辿ってできる四角形の数はいくつか
• ←この場合17です
• (具体的にはテストケースを見よう)
1≦H,W≦150
10.数え上げお兄さん
解法(200点)• カードがどこに置かれているかはどうでもいいので、どこに辺がある
かないかだけ保存しておこう
• 1 1 0 1 1 1 0
• 1 1 0 0 1 1 0
• 1 1 1 1 1 1 1
• 1 1 1 0 1 1 0
• 0 1 0
•
10.数え上げお兄さん
解法• 横線は横方向に何個続いてるか、縦線は縦方向に何個続いているか、
保存しておこう
• 1 2 0 1 1 1 0
• 1 2 0 0 2 2 0
• 1 2 3 1 3 3 1
• 1 2 3 0 4 4 0
• 0 1 0
•
10.数え上げお兄さん
解法• このデータがあれば、左上の点と右下の点を定めた任意の四角形があ
るかないかO(定数(4))程度で判断することができます
• 1 2 0 1 1 1 0
• 1 2 0 0 2 2 0
• 1 2 3 1 3 3 1
• 1 2 3 0 4 4 0
• 0 1 0
• この場合こいつのせいでだめ
(3じゃなきゃだめ)
10.数え上げお兄さん
解法• 確かめるべき四角形は何個あるか?
• 下図は矢印の場所を四角形の右下と定められる四角形の個数
これをH,W=150で全部足すと、
128255625≒10^8
((1~Hの総和)*(1~Wの総和))
定数倍がほぼ4で固定なのでぎりぎり間に合う
(制限時間2sec)(定数倍改善必要かも?)
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
6 12 18 24 30
7 14 21 28 35
10.数え上げお兄さん
別解法• 頭良くDPするのもあるよ。(僕は思いつきませんでした。)
11.新年ゲーム
• 次ページから解説始まります
• (つよっしーのスライドをくっつけたもの)
11.新年ゲーム2
こんにちは、最後の問題を担当したつよっしーです。
この問題は典型を組み合わせただけなので知ってる人にとっては
ただただ実装がつらいだけだったかもしれません。
今年のJOI6問目と酷似しており予選落ちした悲しみを込めて作りました。
11.新年ゲーム2
・部分点解法1
W*Hマスを幅優先探索する。
注意点として、(x,y,体力,縦横)のペアで一つのマスとみること。
Oは(W*H*T)です。
11.新年ゲーム2
・部分点解法2
探索する部分は魔法のマスと回復のマスとゴールだけでよい。
これらのマスをすべて辺でつなぎDijkstraする。
オーダーはO(辺の数log(頂点数))となる。
この時点では探索するマス同士をすべて辺でつないでるため
辺の数が膨大となり満点は取れない
11.新年ゲーム2
・満点解法
先の解法は探索するマス同士をすべて辺で繋いだがそれは無駄
で、四近傍のみ探索すればよい。
オーダーはO(辺の数*log(頂点数))だが辺の数を抑えているた
め満点を取ることが可能。
(この問題と類似した問題としてAOJに「現代的な屋敷」とい
うのがあります。新年ゲーム2は今年のJOI6問目と「現代的
な屋敷」を組み合わせただけです><)
12.最後の一人(謎解き問)
問題概要• 問題文は最後の一人は誰でしょう のみ
• 入力無し
• 出力は一文字
12.最後の一人(謎解き問)
解法(1点)• 出てくる登場人物の名前を整理します
• もうわかるね
• 答えは’R’
n問目 1 2 3 4 5 6 7 8 9 10 11 12
名前 H A P P Y N E W Y E A ?
賞受賞者
らて賞(1人の予定だったけど2人受賞)
• カービィさん
• 電柱君
• もらうものはらてと直接相談してください!
おめでとうございます!
賞受賞者
っこ賞(2人の予定だったけど3人受賞)
• ゲド君
• お米さん
• ならはら君
• (お年「玉」だけに)チョコボール進呈です!
おめでとうございます!
最後に
• 取った点数の西暦に飛ばされるらしいです。
• 総submit数:497• (あと3個提出してくれよ)
• ありがとうございました。
よいお年を