活動日誌'18 No.002

投稿者 NOSS | 2019-03-20

2019/3/20に行われた部内コンテストに出題された問題の概要と解説です

コンテストのリンクはこちら


A問題

NN人の友人とパーティをします。CC人はケーキを持ってきておりii番目の友人が持っていたケーキの数はpip_i個です。全員で均等にケーキを分け私は優先的に11切れもらえるとき、いくつのケーキをもらえるか求めよ。

pip_iの総和をN+1N+1で割った値の切り上げが答え。


B問題

概要

NN以下の素数p,qp,qのうちp+qp+qが素数となるような(p,q)(p,q)の組の個数を求めよ。

  • 1N1071 \le N \le 10^7

解説

p,qp,qがともに奇数であるとき、奇数+奇数=偶数のため素数であることはありません。
よって奇数+偶数しかありえないため22は必ず用います。
22を固定して片側を全探索すればよいです。

計算量は O(NloglogN)O(N \log \log N)


C問題

概要

長さNNの数列aaに対して22つの要素を交換する命令がQQ個与えられる。最初に数列が昇順になるのは何回目の命令か求めよ。

  • 2N31052 \le N \le 3*10^5
  • 1ai1091 \le a_i \le 10^9
  • 1Q31051 \le Q \le 3*10^5

解説

昇順になった状態は一意に定まるためこれを事前に求めておきます。
ソート済の数列と元の数列の同じ位置を比較して、異なるものが00個になったとき昇順になったと判定できます。
命令後に変化するのは22要素のみのため毎回この差分のみを計算すればよいです。

計算量は O(NlogN+Q)O(N \log N + Q)

補足:おそらく O(N+Q)O(N + Q) でも解けますが実装がやや面倒そうです。


D問題

概要

文字列SSが与えられる。SSが猫の鳴き声か判定したい。猫の鳴き声は次のように定義される。

  • 空文字列"“は猫の鳴き声
  • X,Yが猫の鳴き声ならば、’m'+X+‘e’+Y+‘w’は猫の鳴き声
  • 以上で定義されるものだけが猫の鳴き声

SSが猫の鳴き声ならば"Cat"そうでなければ"Rabbit"と出力せよ。

  • 1S5001 ≦ |S| ≦ 500
  • SSは’m’,‘e’,‘w’のみを含む

解説

SSの部分文字列が猫の鳴き声のとき、そこを空文字列に置き換えてもSSが猫の鳴き声かどうかは変わりません。なのでSSの猫の鳴き声の部分を消去していって簡単に判定できるものまで小さくすればよいです。つまり、消去していって最終的な状態が"mew"になっていれば猫の鳴き声です。

消すときは’m’+X+‘e’+Y+‘w’を守るように、“mmewe"を"me"に、“emeww"を"ew"に置換するようにします。

BNFで表されるものは木構造をしているので再帰的な方法でも解けます。


E問題

概要

NN枚の紙があり、ii番目の紙をスキャンするのにかかる時間はTiT_iである。3台のスキャナーを並列に使用したとき、すべての紙をスキャンするのにかかる時間を最小化せよ。

  • 1N501 \le N \le 50
  • 1Ti501 \le T_i \le 50

解説

1番目の紙から順に割り振っていくことを考えてみます。ある時点で区切ったときそれまでどう割り振ったかはその後どう割り振れるかに影響しないのでDPができそうです。なのでそれぞれのスキャナーにどれだけ仕事を割り振ったかを持てばよさそうです。

dp[i][x][y][z]dp[i][x][y][z]=ii番目の紙まで見てそれぞれのスキャナーにx,y,zx,y,z分の仕事を割り振ることが可能か」と置きます。dp[N][x][y][z]dp[N][x][y][z]で可能なもののうち、max(x,y,z)max(x,y,z)の最小値が答えです。
問題はx,y,zx,y,zがどれほどの大きさになるかです。最大ケース N=50,Ti=50(i=1,2,,N)N=50,T_i=50(i=1,2,…,N) を考えるとこの解は850(=50/350)850(= \lceil 50 / 3 \rceil * 50)なので少なくとも解はこれ以下です。

しかし、50(850)350*(850)^3は計算量が大きすぎます。そのため工夫が必要です。

x,y,zx,y,zの関係を見ると Ti=x+y+z\sum T_i = x + y + z が成り立つので z=Tixyz = \sum T_i - x - y より x,yx,yzzを復元できます。よってzzは省略することができます。すると最大でも50(850)250*(850)^2に落ちるのでこれは間に合います。

dp[0][0][0]=truedp[0][0][0] = true 遷移はdp[i][x][y]=truedp[i][x][y] = trueのとき

dp[i+1][x+Ti][y]=true dp[i+1][x][y+Ti]=true dp[i+1][x+T_i][y] = true \\ ~ dp[i+1][x][y+T_i] = true

です。

計算量は O(N(Ti)2)O (N* (\sum T_i)^2) になります。


F問題

概要

本国の首都から姫のいる町まで冷凍された血液を届ける。血液は最大MM分間冷凍しなくても無事である。冷凍しないで1分輸送するごとに無事な残り時間は11分減る。冷凍施設のある町では11分冷凍するごとに無事な残り時間が11分回復する。

血液の冷凍状態を保ったまま輸送するときの首都から姫のいる町への最短時間を求めよ。

  • 2N1002 \le N \le 100
  • 1M1001 \le M \le 100
  • 多重辺、自己ループはない

ただしNNは町の数、MMは再冷凍を行うまでの制限時間を表す。

解説

グラフの最短経路問題ですが、冷凍時間の制約があるため単純には解けません。
そこでグラフを拡張します。d[i][j]d[i][j]を頂点iiに冷凍残り時間jjで到達するときの最短時間とすると、頂点uuからvvへ時間TTかけて移動するとき

d[v][jT]=min(d[v][jT],d[u][j]+T) d[v][j-T] = min(d[v][j-T], d[u][j] + T)

というような遷移が考えられます。また、再冷凍可能な町では

d[i][j+1]=min(d[i][j+1],d[i][j]+1) d[i][j+1] = min(d[i][j+1], d[i][j] + 1)

という遷移ができます。これはダイクストラ法などで解が求められます。

計算量はダイクストラ法で O(KMlogNM)O(KM \log NM)


コメント

B: 意外と偶奇性に気づきにくいです。
C: 1回の命令で変化するものが少ないことに注目します。
D: 構文解析。( )系問題の発展です。
E: DPですが、変数を減らす工夫が必要なので難しいです。
F: 拡張ダイクストラの典型です。

by NOSS