[挑战记录][ZJOI2008]杀蚂蚁
自从有大佬 \(2h\) \(1A\) 杀蚂蚁后,我这个蒟蒻就对这道题充满了向往
于是今天我要挑战一下!
总有地上的的生灵,敢于直面神灵的威光
20221009 10:00
准点开始答题
10:45
被 SMTwy 拉去改宣誓词(悲
11:15
回来了
11:30
去吃火锅(大喜)
14:30
完成了数学部分(计算点到直线距离)
共计用时:1h30min
15:25
完成了蚂蚁行动的部分
用时 2h25min
果然我还是太菜了,两个小时写完的是什么神仙啊
16:33
写完了!开始调弑
\(\cdots\) 10分
用时 3h33min (还挺整)
16:45
30 分,去开大会
18:40
滚回来写
19:36
过了
总计用时(四舍五入)约为 4h45min
交了11遍
果然这就是人和神之间的差距吗!!!
点击查看代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#define int long long
#define WR WinterRain
using namespace std;
const int WR=101,INF=1099511627776;
const double eps=1e-12;
pair<int,int>dir[10];
struct Point{
double x,y;
Point(double _x,double _y){
x=_x,y=_y;
}
Point(){}
Point operator+(const Point &b)const{
Point res;
res=Point(x+b.x,y+b.y);
return res;
}
Point operator-(const Point &b)const{
Point res;
res=Point(x-b.x,y-b.y);
return res;
}
};
struct Map{
int pheromone;
bool vis;
}mp[WR][WR];
struct Turrent{
int goal;
int x,y;
}tur[WR*WR];
struct Ant{
int posx,posy,prex,prey;
int age,level,HP,limHP;
bool cake,dead;
}ant[WR*WR*WR];
int n,m;
int s,d,r;
int t;
int sumant,posant;
int st=1,tag;
bool TakenCake;
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
int sgn(double x){
if(fabs(x)<=eps) return 0;
else return (x>eps?1:-1);
}
double dot(Point a,Point b){
return a.x*b.x+a.y*b.y;
}
double cross(Point a,Point b){
return a.x*b.y-a.y*b.x;
}
double lenth(Point a){
return sqrt(dot(a,a));
}
double get_slope(Point a){
return a.y/a.x;
}
double getdis_segment(Point p,Point a,Point b){
Point vec1,vec2,vec3;
vec1=b-a,vec2=p-a,vec3=p-b;
// printf("%.6lf %.6lf\n",vec1.x,vec1.y);
// printf("%.6lf %.6lf\n",vec2.x,vec2.y);
// printf("%.6lf %.6lf\n",vec3.x,vec3.y);
if(sgn(dot(vec1,vec2))<0) return lenth(vec2);
if(sgn(dot(vec1,vec3))>0) return lenth(vec3);
return fabs(cross(vec1,vec2)/lenth(vec1));
}
double getdis_point(int x1,int y1,int x2,int y2){
return sqrt((double)((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
}
double quick_pow(double a,int b){
double base=a,res=1.0;
while(b){
if(b&1) res*=base;
base*=base;
b>>=1;
}
return res;
}
void Ants_Born(){
if(posant>=6||mp[0][0].vis) return;
posant++,sumant++;
mp[0][0].vis=true;
ant[sumant].level=(sumant-1)/6+1;
ant[sumant].HP=ant[sumant].limHP=floor(4.0*quick_pow(1.1,ant[sumant].level));
ant[sumant].dead=ant[sumant].cake=false;
ant[sumant].age=ant[sumant].posx=ant[sumant].posy=0;
ant[sumant].prex=ant[sumant].prey=INF;
}
void Drop_Pheromone(){
for(int i=st;i<=sumant;i++){
if(ant[i].dead) continue;
if(!ant[i].cake) mp[ant[i].posx][ant[i].posy].pheromone+=2;
else mp[ant[i].posx][ant[i].posy].pheromone+=5;
}
}
void Ants_Move(){
for(int i=st;i<=sumant;i++){
if(ant[i].dead) continue;
int nxtx,nxty,maxph=-1,direc=-1;
for(int j=1;j<=4;j++){
nxtx=ant[i].posx+dir[j].first,nxty=ant[i].posy+dir[j].second;
if(mp[nxtx][nxty].vis||nxtx<0||nxty<0||nxtx>n||nxty>m) continue;
if(nxtx==ant[i].prex&&nxty==ant[i].prey) continue;
if(maxph<mp[nxtx][nxty].pheromone){
maxph=mp[nxtx][nxty].pheromone;
direc=j;
}
}
if((ant[i].age+1)%5==0&&direc!=-1){
for(int j=1;j<=4;j++){
int newdir=(direc-j+3)%4+1;
nxtx=ant[i].posx+dir[newdir].first,nxty=ant[i].posy+dir[newdir].second;
if(mp[nxtx][nxty].vis||nxtx<0||nxty<0||nxtx>n||nxty>m) continue;
// printf("Ant %lld is in crazy mod,turning to (%lld,%lld),pre is (%lld,%ld)\n",i,nxtx,nxty,ant[i].prex,ant[i].prey);
if(nxtx==ant[i].prex&&nxty==ant[i].prey) continue;
direc=newdir;break;
}
}
ant[i].prex=ant[i].posx,ant[i].prey=ant[i].posy;
if(direc==-1) continue;
mp[ant[i].posx][ant[i].posy].vis=false;
ant[i].posx+=dir[direc].first,ant[i].posy+=dir[direc].second;
mp[ant[i].posx][ant[i].posy].vis=true;
// printf("Ant %lld move from (%lld,%lld) to (%lld,%lld)\n",i,ant[i].prex,ant[i].prey,ant[i].posx,ant[i].posy);
}
}
void Check_Cake(){
if(TakenCake) return;
for(int i=st;i<=sumant;i++){
if(ant[i].dead) continue;
if(ant[i].posx==n&&ant[i].posy==m){
tag=i,TakenCake=true,ant[i].cake=true;
ant[i].HP=min(ant[i].HP+(ant[i].limHP>>1),ant[i].limHP);
return;
}
}
}
void Turrent_Fire(){
for(int i=1;i<=s;i++){
double dis_to_tag;
if(TakenCake) dis_to_tag=getdis_point(tur[i].x,tur[i].y,ant[tag].posx,ant[tag].posy);
if(!TakenCake||dis_to_tag-(double)r>eps){
double curdis,mindis=INF;
for(int j=st;j<=sumant;j++){
if(ant[j].dead) continue;
curdis=getdis_point(tur[i].x,tur[i].y,ant[j].posx,ant[j].posy);
if(curdis<mindis){
mindis=curdis;
tur[i].goal=j;
}
}
if(mindis-(double)r>eps){
tur[i].goal=0;
continue;
}
ant[tur[i].goal].HP-=d;
// printf("%lld's goal is %lld\n",i,tur[i].goal);
// printf("Ouch!Ant %lld dropped %lld HP\n",tur[i].goal,d);
}else{
tur[i].goal=tag;
Point b=Point(tur[i].x,tur[i].y),a=Point(ant[tag].posx,ant[tag].posy);
for(int j=st;j<=sumant;j++){
if(ant[j].dead) continue;
if(ant[j].cake){
ant[j].HP-=d;
// printf("Ouch!Ant %lld dropped %lld HP(with cake)\n",j,d);
continue;
}
Point p=Point(ant[j].posx,ant[j].posy);
double dis_to_tur=getdis_segment(p,a,b);
// printf("%lld's dis to segment is %.6lf\n",j,dis_to_tur);
if(dis_to_tur-0.5<eps) ant[j].HP-=d;
// printf("Ouch!Ant %lld dropped %lld HP(not offensive)\n",j,d);
}
}
}
}
void Clear_Battlefield(){
for(int i=st;i<=sumant;i++){
// printf("Ant %lld's blood is %lld\n",i,ant[i].HP);
if(ant[i].dead||ant[i].HP>=0) continue;
posant--;
mp[ant[i].posx][ant[i].posy].vis=false;
ant[i].dead=true;
if(ant[i].cake) tag=TakenCake=ant[i].cake=0;
// printf("Ant %lld dead\n",i);
}
}
bool Check_Win(){
if(!TakenCake) return false;
for(int i=st;i<=sumant;i++){
if((!ant[i].dead)&&(!ant[i].posx)&&(!ant[i].posy)&&ant[i].cake) return true;
}
return false;
}
void Ants_Grow(){
for(int i=st;i<=sumant;i++){
if(ant[i].dead) continue;
ant[i].age++;
}
}
void Pheromone_Disapper(){
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(mp[i][j].pheromone) mp[i][j].pheromone--;
}
}
}
void print(){
printf("%lld\n",posant);
// printf("sum=%lld\n",sumant);
// for(int i=1;i<=sumant;i++) printf("No.%lld ant is %d\n",i,ant[i].dead);
for(int i=st;i<=sumant;i++){
if(ant[i].dead) continue;
printf("%lld %lld %lld %lld %lld\n",ant[i].age,ant[i].level,ant[i].HP,ant[i].posx,ant[i].posy);
}
}
signed main(){
// freopen("test.in","r",stdin);
// freopen("P2586.out","w",stdout);
dir[1]=make_pair(0,1),dir[2]=make_pair(1,0);
dir[3]=make_pair(0,-1),dir[4]=make_pair(-1,0);
n=read(),m=read(),s=read(),d=read(),r=read();
for(int i=1;i<=s;i++) tur[i].x=read(),tur[i].y=read(),mp[tur[i].x][tur[i].y].vis=true;
t=read();
for(int i=1;i<=t;i++){
// printf("%lld\n",i);
Ants_Born();
Drop_Pheromone();
Ants_Move();
Check_Cake();
Turrent_Fire();
Clear_Battlefield();
if(Check_Win()){
printf("Game over after %lld seconds\n",i);
print();
return 0;
}
Ants_Grow();
Pheromone_Disapper();
while(ant[st].dead) st++;
}
printf("The game is going on\n");
print();
return 0;
}
本文来自博客园,作者:冬天丶的雨,转载请注明原文链接:https://www.cnblogs.com/WintersRain/p/16772027.html
为了一切不改变的理想,为了改变不理想的一切