// Author : hejinming2012
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define dbg(x) cout << #x " = " << (x) << endl
#define quickio ios::sync_with_stdio(false);
#define quickin cin.tie(0);
#define quickout cout.tie(0);
#define maxn 1000005
#define inf 4e18
#define eps 1e-10
using namespace std;
inline int read() {
	int now = 0, nev = 1; char c = getchar();
	while(c < '0' || c > '9') { if(c == '-') nev = -1; c = getchar(); }
	while(c >= '0' && c <= '9') { now = (now << 1) + (now << 3) + (c & 15); c = getchar(); }
	return now * nev;
}
void write(int x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
struct Point {
    double x, y;
};
Point inline turn_Point(double x, double y) {
    Point new_Point;
    new_Point.x = x;
    new_Point.y = y;
    return new_Point;
}
Point operator + (Point a, Point b) {
    Point new_Point = turn_Point(a.x + b.x, a.y + b.y);
    return new_Point;
}
Point operator - (Point a, Point b) {
    Point new_Point = turn_Point(a.x - b.x, a.y - b.y);
    return new_Point;
}
int inline double_positive(double x) {
    if(fabs(x) < eps) return 0;
    if(x < 0) return -1;
    return 1;
}
double inline dot(Point a, Point b) {
    double sum = a.x * b.x + a.y * b.y;
    return sum;
}
double inline Length(Point a) {
    double sum = sqrt(dot(a, a));
    return sum;
}
double inline Cross(Point a, Point b) {
    double sum = a.x * b.y - a.y - b.x;
    return sum;
}
double inline get_slope(Point a) {
    double sum = a.y / a.x;
    return sum;
}
double inline get_Point_distant_to_segment(Point p, Point a, Point b) {
    Point Vector1 = b - a;
    Point Vector2 = p - a;
    Point Vector3 = p - b;
    if(double_positive(dot(Vector1, Vector2)) < 0)
        return Length(Vector2);
    if(double_positive(dot(Vector1, Vector3)) > 0)
        return Length(Vector3);
    return fabs(Cross(Vector1, Vector2) / Length(Vector1));
}
int n, m, lst = 1;
struct Map {
    int information_sum;
    bool used;
} G[105][105];
int end_time;
bool game_win = false;
bool cake_fly = false;
int turret_sum;
int turret_radius;
int turret_damage;
int target;
struct Turret {
    int goal, x, y;
} t[105];
int born_ant_sum;
int now_ant_sum;
const double ant_size = 0.5;
struct ant {
    int x, y, old;
    int level, health;
    double born_health;
    int x_from, y_from;
    bool get, dead;
} a[1000000];
void ant_born() {
    if(now_ant_sum >= 6) return ;
    if(G[0][0].used) return ;
    born_ant_sum++;
    now_ant_sum++;
    a[born_ant_sum].x = 0;
    a[born_ant_sum].y = 0;
    a[born_ant_sum].x_from = 99;
    a[born_ant_sum].y_from = 99;
    G[0][0].used = 1;
    a[born_ant_sum].old = 0;
    a[born_ant_sum].level = ((born_ant_sum - 1) / 6) + 1;
    a[born_ant_sum].get = false;
    a[born_ant_sum].dead = false;
    double health = floor(4 * pow(1.1, a[born_ant_sum].level));
    a[born_ant_sum].health = (int) health;
    a[born_ant_sum].born_health = health;
    return ;
}
void inline release_information() {
    for(int i = lst; i <= born_ant_sum; i++) {
        if(a[i].dead) continue ;
        if(!a[i].get) G[a[i].x][a[i].y].information_sum += 2;
        else G[a[i].x][a[i].y].information_sum += 5;
    }
    return ;
}
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
bool inline check_point(int x, int y) {
    if(x < 0) return false;
    if(x > n) return false;
    if(y < 0) return false;
    if(y > m) return false;
    if(G[x][y].used) return false;
    return true;
}
void inline ant_move() {
    for(int i = lst; i <= born_ant_sum; i++) {
        if(a[i].dead) continue ;
        int max_information = -1;
        int now_direction = -1;
        int direction = -1;
        int nowx, nowy, nowd;
        for(int j = 0; j < 4; j++) {
            nowx = a[i].x + dx[j];
            nowy = a[i].y + dy[j];
            if(!check_point(nowx, nowy)) continue ;
            if(nowx == a[i].x_from && nowy == a[i].y_from) continue ;
            if(max_information < G[nowx][nowy].information_sum) {
                max_information = G[nowx][nowy].information_sum;
                direction = j;
            }
        }
        if((a[i].old + 1) % 5 == 0 && direction != -1) {
            max_information = -1;
            now_direction = -1;
            for(int j = 1; j <= 4; j++) {
                nowd = (direction - j) % 4;
                if(nowd < 0) nowd += 4;
                nowx = a[i].x + dx[nowd];
                nowy = a[i].y + dy[nowd];
                if(!check_point(nowx, nowy)) continue ;
                if(nowx == a[i].x_from && nowy == a[i].y_from) continue ;
                if(max_information < G[nowx][nowy].information_sum) {
                    max_information = G[nowx][nowy].information_sum;
                    now_direction = nowd;
                    break ;
                }
            }
        }
        a[i].x_from = a[i].x;
        a[i].y_from = a[i].y;
        if(max_information == -1) continue ;
        if((a[i].old + 1) % 5 == 0) {
            a[i].x += dx[now_direction];
            a[i].y += dy[now_direction];
            G[a[i].x_from][a[i].y_from].used = false;
            G[a[i].x][a[i].y].used = true;
        } else {
            a[i].x += dx[direction];
            a[i].y += dy[direction];
            G[a[i].x_from][a[i].y_from].used = false;
            G[a[i].x][a[i].y].used = true;
        }
    }
    return ;
}
void inline check_cake() {
    if(cake_fly) return ;
    for(int i = lst; i <= born_ant_sum; i++) {
        if(a[i].dead) continue ;
        if(a[i].x == n && a[i].y == m) {
            target = i;
            cake_fly = true;
            a[i].get = true;
            a[i].health += (int) (a[i].born_health / 2);
            a[i].health = min((int) a[i].born_health, a[i].health);
            return ;
        }
    }
    return ;
}
double inline get_distant(int x1, int y1, int x2, int y2) {
    int sum = ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    return sqrt((double) sum);
}
void inline fire_ant() {
    for(int i = 1; i <= turret_sum; i++) {
        double target_distant = get_distant(t[i].x, t[i].y, a[target].x, a[target].y);
        if(!cake_fly || target_distant - (double) turret_radius > eps) {
            double goal_distant;
            double min_distant = inf;
            for(int j = lst; j <= born_ant_sum; j++) {
                if(a[j].dead) continue ;
                goal_distant = get_distant(t[i].x, t[i].y, a[j].x, a[j].y);
                if(goal_distant < min_distant) {
                    min_distant = goal_distant;
                    t[i].goal = j;
                }
            }
            if(min_distant - (double) turret_radius > eps) {
                t[i].goal = 0;
                continue ;
            }
            a[t[i].goal].health -= turret_damage;
        } else {
            t[i].goal = target;
            Point A = turn_Point(a[t[i].goal].x, a[t[i].goal].y);
            Point B = turn_Point(t[i].x, t[i].y);
            for(int j = lst; j <= born_ant_sum; j++) {
                if(a[j].dead) continue ;
                if(a[j].get) {
                    a[j].health -= turret_damage;
                    continue ;
                }
                Point P = turn_Point(a[j].x, a[j].y);
                double not_goal_distant = get_Point_distant_to_segment(P, A, B);
                if(not_goal_distant - ant_size < eps)
                    a[j].health -= turret_damage;
            }
        }
    }
}
void inline clear_bullet_field() {
    for(int i = lst; i <= born_ant_sum; i++) {
        if(a[i].health >= 0) continue ;
        if(!G[a[i].x][a[i].y].used) continue ;
        if(a[i].dead) continue ;
        now_ant_sum--;
        G[a[i].x][a[i].y].used = false;
        a[i].x = 99;
        a[i].y = 99;
        a[i].dead = true;
        if(a[i].get) {
            cake_fly = false;
            target = 0;
        }
    }
}
void inline check_game_continue() {
    if(!cake_fly) return ;
    for(int i = lst; i <= born_ant_sum; i++) {
        if(a[i].dead) continue ;
        if(a[i].x || a[i].y) continue ;
        if(!a[i].get) continue ;
        game_win = true;
        break ;
    }
    return ;
}
void inline ant_grow() {
    for(int i = lst; i <= born_ant_sum; i++) {
        if(a[i].dead) continue ;
        a[i].old++;
    }
    return ;
}
void inline information_gone() {
    for(int i = 0; i <= n; i++)
        for(int j = 0; j <= m; j++)
            if(G[i][j].information_sum)
                G[i][j].information_sum--;
    return ;
}
void inline input() {
    n = read(), m = read();
    turret_sum = read();
    turret_damage = read();
    turret_radius = read();
    for(int i = 1; i <= turret_sum; i++) {
        t[i].x = read();
        t[i].y = read();
        G[t[i].x][t[i].y].used = true;
    }
    end_time = read();
    return ;
}
void inline work() {
    for(int Time = 1; Time <= end_time; Time++) {
        ant_born();
        release_information();
        ant_move();
        check_cake();
        fire_ant();
        clear_bullet_field();
        check_game_continue();
        if(game_win) {
            printf("Game over after %lld seconds\n", Time);
            break ;
        }
        ant_grow();
        information_gone();
        for(int i = lst; i <= born_ant_sum; i++)
            if(a[i].dead) continue ;
            else { lst = i; break ; }
    }
    return ;
}
void inline output() {
    if(!game_win) puts("The game is going on");
    printf("%lld\n", now_ant_sum);
    for(int i = lst; i <= born_ant_sum; i++) {
        if(a[i].dead) continue ;
        write(a[i].old), putchar(' ');
        write(a[i].level), putchar(' ');
        write(a[i].health), putchar(' ');
        write(a[i].x), putchar(' ');
        write(a[i].y), putchar(10);
    }
    return ;
}
signed main() {
    quickio
    quickin
    quickout
    input();
    work();
    output();
    return 0;
}

0 条评论

目前还没有评论...

信息

ID
1534
时间
1000ms
内存
256MiB
难度
9
标签
(无)
递交数
12
已通过
5
上传者