ABC 246
Table of Contents
A - Four Points
辺が $x$ 軸に平行または $y$ 軸に平行であるから, 長方形を構成する4点に関して $x$ 座標が同じ点が2つずつ, $y$ 座標が同じ点が2つずつある.
この問題では3点が与えられるので残る1点の座標は
- $x$ 座標: 3点の $x$ 座標の XOR
- $y$ 座標: 3点の $y$ 座標の XOR
となる.
B - Get Closer
$(A, B)$ 方向への単位ベクトルを求めれば良いので $\displaystyle \left(\frac{A}{\sqrt{A^2 + B^2}}, \frac{B}{\sqrt{A^2 + B^2}} \right)$ が答え.
C - Coupon
まず各商品に対して $\frac{A_i}{X}$ 枚のクーポンを使う. クーポンが足りなくなったらそのまま.
クーポンが余った場合, 各商品に払わないといけない金額は $X$ 未満になっているので, 残高が高い順にクーポンを適用させていけばよい.
D - 2-variable Function
$f(a,b) = a^3 + a^2b + ab^2 + b^3$ とする. $f(a,b) \geq N$ を満たす最小の $f(a, b)$ を求める.
$N \leq 10^{18}$ より $0 \leq a, b \leq 10^6$ である. $a$, $b$ は非負整数であるから $f(a,b)$ は $a$, $b$ に関して増加関数である. よって $a$ を固定したときの $f(a, b) \geq N$ を満たす最小の $f(a, b)$ を $f_a(b_{\mathrm{min}})$ とすると $f_a(b_{\mathrm{min}})$ は $b$ を二部探索することでもとめることができる. すべての $a$ に関して $f_a(b_{\mathrm{min}})$ を求めたときその最小値が答えとなる.
計算量は $N^{1/3} \log N^{1/3}$.
E - Bishop 2
一つ前の移動と同じ方向へ進む場合はコスト 0 で移動し, 違う方向に進む場合はコスト 1 で移動する. これをダイクストラ風にして解く.
int di[] = {-1, -1, 1, 1};
int dj[] = {-1, 1, -1, 1};
struct Point {
int i, j, dir, cost;
};
bool operator>(const Point& a, const Point& b) {
return a.cost > b.cost;
}
void solve() {
int n;
cin >> n;
int ax, ay, bx, by;
cin >> ax >> ay >> bx >> by;
ax--, ay--, bx--;
by--;
vector<string> board(n);
rep(i, n) cin >> board[i];
vvint dist(n, vint(n, INF));
dist[ax][ay] = 0;
priority_queue<Point, vector<Point>, greater<Point>> pq;
pq.push({ax, ay, 4, 0});
vector<vvint> done(n, vvint(n, vint(5)));
while (pq.size()) {
auto [x, y, dir, cost] = pq.top();
pq.pop();
if (done[x][y][dir])
continue; // これを入れないと TLE する.
// 入れなかった場合, 確定したところをもう一度探索してしまうため.
done[x][y][dir] = 1;
rep(d, 4) {
int nx = x + di[d], ny = y + dj[d];
if (nx < 0 || nx >= n || ny < 0 || ny >= n)
continue;
if (board[nx][ny] == '#')
continue;
int inc = (dir == d) ? 0 : 1;
if (dist[nx][ny] >= cost + inc) { // 距離は同じでも違う方向からくるパターンもあるので = を加える
dist[nx][ny] = cost + inc;
pq.push({nx, ny, d, cost + inc});
}
}
}
if (dist[bx][by] == INF)
cout << -1 << endl;
else
cout << dist[bx][by] << endl;
}