TIOJ 2000:TIOJ 2000 特別紀念題:Charles
TIOJ 2000:TIOJ 2000 特別紀念題:Charles
題目大意:見題敘,總之就是有很多球球想要碰到你,而你要操縱自己的位置讓遊戲時間盡可能長,然後會有一些道具。
解法:這題感覺好像 $\text{AHC}$,我的做法可能還要加一些運氣成分才會 $\text{AC}$,首先我先找出所有小球的位置,並把四個角落的位置也加進去,然後我去算我的位移量,盡可能往小球反方向走,並且離越近貢獻的量就越多,過程中可能會有一些 $\text{random}$,自己實測大概要十幾次才會使遊戲時間符合條件,所以我改變 $\text{seed}$ 的值,上傳了幾十次就 $\text{AC}$ 了。
這也是我在 $\text{TIOJ}$ 上的第 $1000$ 題!
$\text{Code:}$
#include <bits/stdc++.h>
#include "lib2000.h"
using namespace std;
mt19937 seed (34);
inline int rnd (int l, int r) {
return uniform_int_distribution<int> (l, r) (seed);
}
inline float rrnd (float l, float r) {
return uniform_real_distribution<float> (l, r) (seed);
}
void init() {}
inline void add (float &x, float dx) {
x += rrnd (-0.2, 1.0) / (dx * dx * dx);
}
pos_type play() {
auto ball = get_ball();
auto ball_spec = get_ball_spec();
auto [nx, ny] = get_pos();
float xsum = 0, ysum = 0;
for (float i = 0; i <= 100; i += 100) {
ball.push_back ({i, 0.0f});
ball.push_back ({i, 50.0f});
}
for (float i = 0; i <= 50; i += 50) {
ball.push_back ({0.0f, i});
ball.push_back ({100.0f, i});
}
for (auto &[x, y] : ball) {
float dx = nx - x, dy = ny - y;
if (dx == 0 && dy == 0) continue;
if (dx == 0) {add (ysum, dy); continue;}
if (dy == 0) {add (xsum, dx); continue;}
add (xsum, dx), add (ysum, dy);
}
for (auto &[x, y] : ball_spec) {
float dx = nx - x, dy = ny - y;
if (dx == 0 && dy == 0) continue;
if (dx == 0) {add (ysum, dy); continue;}
if (dy == 0) {add (xsum, dx); continue;}
add (xsum, dx), add (ysum, dy);
}
if (xsum == 0 && ysum == 0) {
return {nx, ny};
}
float sum = sqrt (xsum * xsum + ysum * ysum);
xsum /= sum, xsum *= rrnd (0.5, 2);
ysum /= sum, ysum *= rrnd (0.5, 2);
return {nx + xsum, ny + ysum};
}
我的分享就到這裡結束了,如果喜歡我的 $\text{Blog}$,歡迎追蹤!
留言
張貼留言