bzoj1033: [ZJOI2008]杀蚂蚁antbuster
2014-06-02 20:41
429 查看
刚开博客,放几道大模拟
杀蚂蚁
www.lydsy.com/JudgeOnline/problem.php?id=1033
杀蚂蚁
www.lydsy.com/JudgeOnline/problem.php?id=1033
#include <cstdio> #include <cmath> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define MAXN 10 #define MAXM 10 #define EPS (1e-8) struct Point { int x, y; Point(int _x = 0, int _y = 0) : x(_x), y(_y) {} bool operator== (const Point &a)const { return x == a.x && y == a.y; } bool operator!= (const Point &a)const { return x != a.x || y != a.y; } }; double dis(const Point &a, const Point &b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } struct Ant { Point pos, last; long age, k, blood, life, active; bool cake; Ant(Point _pos, Point _last, long _age, long _k, long _blood, long _life, long _active, bool _cake) : pos(_pos), last(_last), age(_age), k(_k), blood(_blood), life(_life), active(_active), cake(_cake) {} bool operator< (const Ant &x)const { return age > x.age; } }; int n, m, d, r; long T; vector<Point> turret; vector<Ant> ant; long antct; long info[MAXN][MAXN]; int hasant[MAXN][MAXN]; bool hasturret[MAXN][MAXN]; bool hascake; void Init() { hascake = true; antct = 0; memset(info, 0, sizeof(info)); memset(hasant, 0, sizeof(hasant)); memset(hasturret, 0, sizeof(hasturret)); scanf("%d%d", &n, &m); int s; scanf("%d%d%d", &s, &d, &r); while (s--) { int x, y; scanf("%d%d", &x, &y); turret.push_back(Point(x, y)); hasturret[x][y] = true; } scanf("%ld", &T); } void NewAnt() { if (ant.size() < 6 && !hasant[0][0]) { long k = antct++ / 6 + 1; long blood = 4 * pow(1.1, k); ant.push_back(Ant(Point(0, 0), Point(0, 0), 0, k, blood, blood, 0, false)); ++hasant[0][0]; } } void CreatInfo() { for (vector<Ant>::iterator i = ant.begin(); i != ant.end(); ++i) info[i->pos.x][i->pos.y] += (i->cake ? 5 : 2); } bool check(int x, int y) { return x >= 0 && y >= 0 && x <= n && y <= m && !hasant[x][y] && !hasturret[x][y]; } int g[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; void MoveOne(vector<Ant>::iterator x) { ++x->active; vector<int> cango; for (int i = 0; i < 4; ++i) if (check(x->pos.x + g[i][0], x->pos.y + g[i][1]) && Point(x->pos.x + g[i][0], x->pos.y + g[i][1]) != x->last) cango.push_back(i); if (cango.size() == 0) { x->last = x->pos; return; } long maxinfo = 0; for (vector<int>::iterator i = cango.begin(); i != cango.end(); ++i) maxinfo = max(maxinfo, info[x->pos.x + g[*i][0]][x->pos.y + g[*i][1]]); for (vector<int>::iterator i = cango.begin(); i != cango.end();) if (maxinfo == info[x->pos.x + g[*i][0]][x->pos.y + g[*i][1]]) ++i; else i = cango.erase(i); Point t; if (x->active % 5) t = Point(x->pos.x + g[cango[0]][0], x->pos.y + g[cango[0]][1]); else for (int i = 1; i <= 4; ++i) if (check(x->pos.x + g[(cango[0] - i + 4) % 4][0], x->pos.y + g[(cango[0] - i + 4) % 4][1]) && x->last != Point(x->pos.x + g[(cango[0] - i + 4) % 4][0], x->pos.y + g[(cango[0] - i + 4) % 4][1])) { t = Point(x->pos.x + g[(cango[0] - i + 4) % 4][0], x->pos.y + g[(cango[0] - i + 4) % 4][1]); break; } x->last = x->pos; x->pos = t; } void AntMove() { for (vector<Ant>::iterator i = ant.begin(); i != ant.end(); ++i) { --hasant[i->pos.x][i->pos.y]; MoveOne(i); ++hasant[i->pos.x][i->pos.y]; if (i->pos.x == n && i->pos.y == m && hascake) { i->blood += i->life / 2; if (i->blood > i->life) i->blood = i->life; hascake = false; i->cake = true; } } } typedef Point Vector; Vector operator- (const Point &a, const Point &b) { return Vector(a.x - b.x, a.y - b.y); } struct Line { Point p; Vector v; Line(const Point &a, const Point &b) : p(a), v(b - a) {} }; int dcmp(double a) { if (fabs(a) <= EPS) return 0; return a > 0 ? 1 : -1; } int GetCut(const Line &L, const Point &C, double &t1, double &t2) { double a = L.v.x, b = L.p.x - C.x, c = L.v.y, d = L.p.y - C.y; double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - 0.25; double delta = f * f - 4 * e * g; if (dcmp(delta) < 0) return 0; if (dcmp(delta) == 0) { t1 = t2 = -f / (2 * e); return 1; } t1 = (-f - sqrt(delta)) / (2 * e); t2 = (-f + sqrt(delta)) / (2 * e); return 2; } bool CanAttack(const Point &a, const Point &b, const Point &c) { double t1, t2; int k = GetCut(Line(a, b), c, t1, t2); if (k == 0) return false; if (k == 1) return dcmp(t1) >= 0 && dcmp(t1 - 1) <= 0; else return (dcmp(t1) >= 0 && dcmp(t1 - 1) <= 0) || (dcmp(t2) >= 0 && dcmp(t2 - 1) <= 0); } void TurretAct() { for (vector<Point>::iterator i = turret.begin(); i != turret.end(); ++i) { Point p(-1, -1); double dp; for (vector<Ant>::iterator j = ant.begin(); j != ant.end(); ++j) { double d = dis(*i, j->pos); if (d <= r) if (p.x == -1 || j->cake || dcmp(d - dp) < 0) { p = j->pos; dp = d; if (j->cake) break; } } if (p.x != -1) for (vector<Ant>::iterator j = ant.begin(); j != ant.end();++j) if (CanAttack(*i, p, j->pos)) j->blood -= d; } for (vector<Ant>::iterator i = ant.begin(); i != ant.end();) if (i->blood < 0) { --hasant[i->pos.x][i->pos.y]; if (i->cake) hascake = true; i = ant.erase(i); } else ++i; } bool AntWin() { if (hascake) return false; for (vector<Ant>::iterator i = ant.begin(); i != ant.end(); ++i) if (i->cake && i->pos.x == 0 && i->pos.y == 0) return true; return false; } void ShowAnt() { printf("%d\n", ant.size()); sort(ant.begin(), ant.end()); for (vector<Ant>::iterator i = ant.begin(); i != ant.end(); ++i) printf("%ld %ld %ld %d %d\n", i->age, i->k, i->blood, i->pos.x, i->pos.y); } void DecreaseInfo() { for (int i = 0; i <= n; ++i) for (int j = 0; j <= m; ++j) if (info[i][j]) --info[i][j]; } void AntGrow() { for (vector<Ant>::iterator i = ant.begin(); i != ant.end(); ++i) ++i->age; } int main() { Init(); for (long i = 1; i <= T; ++i) { NewAnt(); CreatInfo(); AntMove(); TurretAct(); if (AntWin()) { printf("Game over after %ld seconds\n", i); ShowAnt(); return 0; } DecreaseInfo(); AntGrow(); } printf("The game is going on\n"); ShowAnt(); return 0; }
相关文章推荐
- 【BZOJ1033】[ZJOI2008]杀蚂蚁antbuster
- bzoj1033 [ZJOI2008]杀蚂蚁antbuster
- bzoj1033: [ZJOI2008]杀蚂蚁antbuster
- BZOJ 1033 [ZJOI2008]杀蚂蚁antbuster 模拟
- 【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster
- BZOJ 1033: [ZJOI2008]杀蚂蚁antbuster(模拟)
- 【BZOJ1033】[ZJOI2008]杀蚂蚁antbuster【模拟】
- [BZOJ 1033] [ZJOI2008] 杀蚂蚁antbuster 【模拟!】
- 【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster
- BZOJ 1033: [ZJOI2008]杀蚂蚁antbuster
- bzoj千题计划121:bzoj1033: [ZJOI2008]杀蚂蚁antbuster
- [BZOJ 1033][ZJOI2008]杀蚂蚁antbuster
- [BZOJ1033][ZJOI2008]杀蚂蚁antbuster(大模拟)
- 【BZOJ1033】[ZJOI2008]杀蚂蚁antbuster【模拟】
- 【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster(判断线段是否和圆相交)
- bzoj 1033【ZJOI2008】杀蚂蚁
- [bzoj1033] [ZJOI2008]杀蚂蚁 Big MoNI
- 【模拟】【计算几何】[ZJOI2008][HYSBZ/BZOJ1033]杀蚂蚁antbuster
- bzoj1033: [ZJOI2008]杀蚂蚁antbuster
- 模拟 [ZJOI2008]杀蚂蚁antbuster