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}$,歡迎追蹤! 

留言

熱門文章