5. Div2 Medium : MinimumSquareEasy
解答例(C#)
public long minArea(int[] x, int[] y) {
int n = x.Length;
long minSide = long.MaxValue;
for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {
var xs = new List<int>();
var ys = new List<int>();
for (int k = 0; k < n; k++) {
if (i == k || j == k) continue;
xs.Add(x[k]);
ys.Add(y[k]);
}
var side = Math.Max(xs.Max() - xs.Min(), ys.Max() - ys.Min()) + 2;
minSide = Math.Min(minSide, side);
}
return minSide * minSide;
}
6. Div1 Easy : MinimumSquare
問題
• N 個の二次元座標が与えられる ( 2 ≦ N ≦ 100 )
• このうち少なくとも K 個の点を ( 1 ≦ K ≦ N )
内側(境界上はNG)に含むような正方形の最小面積を求めよ
• ただし、「正方形の辺は垂直または水平」
「正方形の頂点は整数座標」でないといけない
15. Div2 Hard : TorusSailingEasy
( a % N, a % M) = (goalX, goalY) であるような最小の自然数 a
(-b % N, -b % N) = (goalX, goalY) であるような最小の自然数 b
を使って、
「0 から +1 または -1 にランダム・ウォークしたとき、 a または –b
に到達するまでの移動回数の期待値を求めよ」 と言い換えられる
ab
16. Div2 Hard : TorusSailingEasy
a, b の求め方いろいろ
• 0 から M*N-1 までの整数を全探索する
• 計算量: O(MN)
• (p % N == goalX) な整数 p だけを探索する
• 例: for (int p = goalX; p < N * M; p += N) if (p % M == goalY) return p;
• 計算量: O(M)
• 中国剰余定理で連立合同式を解く
• 計算量: O(log(N)) or O(log(M))
N,M ≦ 10 のため、どれでも十分間に合う
17. Div2 Hard : TorusSailingEasy
期待値の求め方(連立方程式を解く方法)
E[x] = x からゴールへ到達する移動回数の期待値
とすると
E[a] = 0,E[-b] = 0,E[i] = (E[i+1] + E[i-1]) / 2 + 1 (-b < i < a)
となり、(a + b + 1) 変数連立方程式を導出できる
N 変数連立方程式はガウスジョルダン法やガウスの消去法 など
を使うと O(N^3) で解けるため、計算量は O((MN)^3)となる。
24. Div2 Hard : TorusSailingEasy
期待値の求め方(動的計画法)
(a + b) が偶数の場合 - まとめ
• 変形後のゴール位置 G = (a + b) / 2
• 変形後のスタート位置 S = G – min(a, b)
• S から G までの移動回数の期待値
Eeven [S,G] = (G + S) (G – S)
• 計算量: O(1)
26. Div2 Hard : TorusSailingEasy
期待値の求め方(動的計画法)
(a + b) が奇数の場合
• p から(p+1)までの移動回数の期待値 E[p] = 2 * p
• 0 から p までの移動回数の期待値
= E[0] + E[1] + … + E[p-1]
= 2 + 4 + 6 + … + 2 * (p-1) = p * (p + 1)
• x から y までの移動回数の期待値 Eodd[x,y] (x < y)
= E[x] + E[x+1] … + E[y-1]
= (E[0] + E[1] + .. + E[y-1]) – (E[0] + E[1] + … E[x-1])
= y*(y+1) – x*(x+1) = y^2-x^2+y-x
=(y+x)(y-x)+(y-x) = (y+x+1)(y-x)
27. Div2 Hard : TorusSailingEasy
期待値の求め方(動的計画法)
(a + b) が奇数の場合 - まとめ
• 変形後のゴール位置 G = (a + b - 1) / 2
• 変形後のスタート位置 S = G – min(a, b)
• S から G までの移動回数の期待値
Eodd[S,G] = (G + S + 1) (G – S)
• 計算量: O(1)
28. Div2 Hard : TorusSailingEasy
期待値の求め方(別解: a*b)
実は期待値は
a * b になります。
• 計算量: O(1)
29. Div2 Hard : TorusSailingEasy
期待値の求め方(別解: a*b)
(a + b) が偶数の場合
• G = (a + b) / 2, S = G – min(a, b)
• G – S = min(a, b)
• G + S = 2 * G – min(a, b) = a + b – min(a,b)
• (G + S) (G – S) = (a + b – min(a,b)) * min(a,b)
= a * b
30. Div2 Hard : TorusSailingEasy
期待値の求め方(別解: a*b)
(a + b) が奇数の場合
• G = (a + b - 1) / 2
S = G – min(a, b)
• G – S = min(a, b)
• G + S + 1 = 2 * G – min(a, b) + 1 = a + b – min(a,b)
• (G + S + 1) (G – S) = (a + b – min(a,b)) * min(a,b)
= a * b
31. Div2 Hard : TorusSailingEasy
解答例(C#)
int reach(int N, int M, int x, int y) {
for (int p = x; p < N * M; p += N) if (p % M == y) return p;
return -1;
}
public double expectedTime(int N, int M, int goalX, int goalY) {
var a = reach(N, M, goalX, goalY);
var b = reach(N, M, (N - goalX) % N, (M - goalY) % M);
if (a == -1 || b == -1) return -1;
return 1.0 * a * b ;
}
32. Div1 Hard : TorusSailing
問題
• 格子状に N × M のエリアがある。
• シエルは (0,0) からスタートする
• シエルは、もし(x, y) にいる場合は
• (x % N, (y + 1) % M)
• ((x + 1) % N, y % M)
のどちらに等確率で移動する
• (goalX, goalY) に到達するまでの移動回数の期待値を求めよ