您的位置:首页 > 其它

[ZJOI2008] 杀蚂蚁(BZOJ上未过)

2018-01-09 13:39 337 查看
       dark模拟题。

       计算几何一片空白判线段和圆是否相交来来回回改了五六次,代码也写得很长(还有一部分原因是码风问题233)

       提交记录非常鬼畜:先在Codevs上WA40,把inline全部去掉就AC了;再到洛谷上还是WA40,把O2关掉变成80,数组开大点就AC了。但是BZOJ上还是WA。

       如果哪位大佬帮我看出哪里有点问题(也有可能是比较危险的未定义行为)或者有叉掉我的数据麻烦指出一下,非常感激。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<time.h>
#include<vector>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define LL long long
#define int long long
using namespace std;
const int N=2e5+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const int u[4]={0,1,0,-1};
const int v[4]={1,0,-1,0};

namespace FastIO {
template<typename tp> void read(tp &x) {
x=0; register char c=getchar(); register bool f=0;
for(;c<'0'||c>'9';f|=(c=='-'),c = getchar());
for(;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0',c = getchar());
if(f) x=-x;
}
template<typename tp> void write(tp x) {
if (x==0) return (void) (putchar('0'));
if (x<0) putchar('-'),x=-x;
int pr[20]; register int cnt=0;
for (;x;x/=10) pr[++cnt]=x%10;
while (cnt) putchar(pr[cnt--]+'0');
}
template<typename tp> void writeln(tp x) {
write(x);
putchar('\n');
}
}
using namespace FastIO;

int n,m,T,s,d,r,t,Game_end;
int AntIn[15][15],HP_Level
;

struct Point {
int InMap,num;
}Map[15][15];

namespace Information_Ant {
int ord,Num_Ant,target;
struct Ant {
int x,y,lasx,lasy;
int HP,time,cake,level,blood;
}ant[10],move[10];

void Ant_Born() {
if (Num_Ant>=6||AntIn[1][1]) return;
ord++; Num_Ant++; int lev=(ord-1)/6+1,HP=HP_Level[lev];
ant[Num_Ant]=(Ant) {1,1,0,0,HP,0,0,lev,HP};
AntIn[1][1]=1;
}

void Ant_Put() {
for (int i=1;i<=Num_Ant;i++) {
int x=ant[i].x,y=ant[i].y;
Map[x][y].num+=(i==target)?5:2;
}
}

int Can_Go(int x,int y) {
if (!Map[x][y].InMap) return 0;
if (AntIn[x][y]) return 0;
return 1;
}

int Pre(int x) {
return (!x)?3:x-1;
}

void Ant_Move(int p) {
int x=ant[p].x,y=ant[p].y,lasx=ant[p].lasx,lasy=ant[p].lasy;
int to=-1,maxn=-inf,tot=0;
for (int i=0;i<4;i++) {
if (x+u[i]==lasx&&y+v[i]==lasy) continue;
if (Can_Go(x+u[i],y+v[i])) {
if (maxn<Map[x+u[i]][y+v[i]].num) maxn=Map[x+u[i]][y+v[i]].num,tot=1,to=i;
else if (maxn==Map[x+u[i]][y+v[i]].num) tot++;
}
}
if (~to&&tot>1) {
for (int i=0;i<4;i++) {
if (x+u[i]==lasx&&y+v[i]==lasy) continue;
if (Can_Go(x+u[i],y+v[i])&&Map[x+u[i]][y+v[i]].num==maxn) {
to=i;
break;
}
}
}
if (~to&&ant[p].time%5==4) {
for (int i=Pre(to);i!=to;i=Pre(i)) {
if (x+u[i]==lasx&&y+v[i]==lasy) continue;
if (Can_Go(x+u[i],y+v[i])) {
to=i;
break;
}
}
}
ant[p].lasx=x; ant[p].lasy=y;
if (~to) {
AntIn[x][y]=0;
x+=u[to]; y+=v[to];
AntIn[x][y]=1;
ant[p].x=x; ant[p].y=y;
}
if (target==-1&&x==n&&y==m) {
target=p;
ant[p].cake=1;
ant[p].HP=min(ant[p].blood,ant[p].HP+ant[p].blood/2);
}
}

void Ant_Die() {
int alive=0;
for (int i=1;i<=Num_Ant;i++) {
if (ant[i].HP>=0) move[++alive]=ant[i];
else AntIn[ant[i].x][ant[i].y]=0;
}
for (int i=1;i<=alive;i++)
ant[i]=move[i];
Num_Ant=alive; target=-1;
for (int i=1;i<=alive;i++)
if (ant[i].cake) target=i;
}

};
using namespace Information_Ant;

namespace Information_Tower {
struct Vector {
int x,y;
int Dot(Vector &b) {
return x*b.x+y*b.y;
}
}tower[200];

int Dis(int p,int q) {
int x=abs(tower[p].x-ant[q].x);
int y=abs(tower[p].y-ant[q].y);
return x*x+y*y;
}

int Can_Attack(int p,int goal) {
return Dis(p,goal)<=r*r;
}

int Check_Ver(int u,int v,int w) {
Vector a=(Vector) {tower[u].x-ant[v].x,tower[u].y-ant[v].y};
Vector b=(Vector) {ant[w].x-ant[v].x,ant[w].y-ant[v].y};
return a.Dot(b)>=0;
}

int Attacked(int p,int q,int goal) {
if (q==goal) return 1;
tower[0]=(Vector) {ant[goal].x,ant[goal].y};
ant[0].x=tower[p].x; ant[0].y=tower[p].y;
if (Check_Ver(p,goal,q)&&Check_Ver(0,0,q)) {
int x1=ant[q].x-tower[p].x,y1=ant[q].y-tower[p].y;
int x2=ant[goal].x-tower[p].x,y2=ant[goal].y-tower[p].y;
int dx=(x1*y2-x2*y1)*(x1*y2-x2*y1);
int dy=(x2*x2+y2*y2)/4;
return dx<=dy;
}
}

void Tower_Attack(int p) {
if (~target&&Can_Attack(p,target)) {
for (int i=1;i<=Num_Ant;i++)
if (Attacked(p,i,target)) ant[i].HP-=d;
return;
}
int minv=inf,goal=-1;
for (int i=1;i<=Num_Ant;i++) {
int dx=Dis(p,i);
if (dx<=r*r&&dx<minv) minv=dx,goal=i;
}
if (~goal)
for (int i=1;i<=Num_Ant;i++) {
if (Attacked(p,i,goal)) ant[i].HP-=d;
}
}

}
using namespace Information_Tower;

void Init() {
read(n); read(m); n++; m++;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
Map[i][j].InMap=1;
read(s); read(d); read(r);
for (int i=1;i<=s;i++) {
int x,y;
read(x); read(y); x++; y++;
tower[i].x=x; tower[i].y=y;
Map[x][y].InMap=0;
}
read(T); target=-1;
}

int Check_Over() {
if (target==-1) return 0;
return ant[target].x==1&&ant[target].y==1;
}

void Second_End() {
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (Map[i][j].num) Map[i][j].num--;
for (int i=1;i<=Num_Ant;i++) ant[i].time++;
}

int Game(int T) {
Ant_Born();
Ant_Put();
for (int i=1;i<=Num_Ant;i++) Ant_Move(i);
for (int i=1;i<=s;i++)
Tower_Attack(i);
Ant_Die();
if (Check_Over()) return 0;
Second_End();
return 1;
}

void Output() {
writeln(Num_Ant);
for (int i=1;i<=Num_Ant;i++) {
printf("%lld %lld %lld %lld %lld\n",ant[i].time,ant[i].level,ant[i].HP,ant[i].x-1,ant[i].y-1);
}
}

signed main() {
Init();
double x=1;
for (int i=1;i<=200000;i++) {
x*=1.1;
HP_Level[i]=4*x;
}
for (t=1;t<=T;t++) {
if (!Game(t)) {
Game_end=1;
printf("Game over after %lld seconds\n",t);
break;
}
}
if (!Game_end) printf("The game is going on\n");
Output();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: