[ZJOI2008]杀蚂蚁antbuster 题解
一个题目的可读版本:https://www.zybuluo.com/Jerusalem/note/221811
这两天做的又一道大模拟题,感觉这玩意有毒,会上瘾啊……
比起猪国杀这道题真心不知道高到哪里去了,当然,我只是说题目。具体难度说句实在地,真觉得比猪国杀要容易一些。
先说一下时间线:
第一天下午:打完猪国杀,立志杀蚂蚁。
第二天下午:3:00 开搞,读题,扫雷。
3:30 正式打码。
5:20 代码完成,开始调试。
6:00 解决肚子问题
6:25 回来继续搞
6:31 AC!!
比起猪国杀那长征般的的历程,不得不去说杀蚂蚁要简单太多太多了。至少从代码长度就可以看出来。
先说一些坑点:
1.刚出生的蚂蚁年龄是0。
2.行动方式变化的蚂蚁(年龄+1)%5==0而不是年龄%5=0。
3.对于一些较复杂的求蚂蚁与塔之间的连线的解析式的方法可能会被卡精度,再次感谢原子核教我的解方程式打法避免被卡精度。
4.大视野上的注释有误。
5.蚂蚁死了之后他原来位置上记得标记为无蚂蚁。
还是那句话,比猪国杀强多了。
然后,我们只要按照题目中给出的“一秒钟发生的事”的顺序打出对应函数就好了,毕竟只是模拟题,只要不太浪,单纯的模拟是不会T掉的。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#define N 200004
using namespace std;
int n,m,s,d,r,t,js,zz,target,zy[5][2];
struct tow
{
int x,y;
}tower[50];
struct an
{
int age,level,hp,x,y,lx,ly,id;
}ant[N];
struct ma
{
bool tower,ant;
int inf;
}map[10][10];
int pre[N],fro[N];
void print(int x)
{
printf("%d %d %d %d %d\n",ant[x].age,ant[x].level,ant[x].hp,ant[x].x,ant[x].y);
}
void born()
{
if(js<6&&!map[0][0].ant)
{
js++;
zz++;
ant[zz].age=0; ant[zz].id=zz;
ant[zz].level=(zz-1)/6+1;
ant[zz].hp=4*pow(1.1,ant[zz].level);
map[0][0].ant=1;
ant[zz].x=ant[zz].y=0;
pre[zz]=pre[0]; fro[zz]=0;
fro[pre[0]]=zz; pre[0]=zz;
}
}
void stay_information()
{
int now=fro[0];
while(now)
{
map[ant[now].x][ant[now].y].inf+=2;
if(target==now)map[ant[now].x][ant[now].y].inf+=3;
now=fro[now];
}
}
bool check(int x,int y)
{
if(map[x][y].tower||map[x][y].ant)return 0;
if(x<0||y<0)return 0;
if(x>n||y>m)return 0;
return 1;
}
void move_an_ant(int aa)
{
int x=ant[aa].x,y=ant[aa].y;
bool yx=1;
int mx=-1,to=0;
for(int i=1;i<=4;i++)
{
int tx=x+zy[i][0],ty=y+zy[i][1];
if(!check(tx,ty)||(tx==ant[aa].lx&&ant[aa].ly==ty))continue;
if(mx<map[tx][ty].inf)
{
to=i;
mx=map[tx][ty].inf;
}
}
if((ant[aa].age+1)%5==0)
{
int la=to;
for(int i=to-1;i>0;i--)
{
int tx=x+zy[i][0],ty=y+zy[i][1];
if(!check(tx,ty)||(tx==ant[aa].lx&&ant[aa].ly==ty))continue;
to=i;
break;
}
if(to==la)
{
for(int i=4;i>=to;i--)
{
int tx=x+zy[i][0],ty=y+zy[i][1];
if(!check(tx,ty)||(tx==ant[aa].lx&&ant[aa].ly==ty))continue;
to=i;
break;
}
}
}
map[x][y].ant=0;
ant[aa].lx=ant[aa].x,ant[aa].ly=ant[aa].y;
ant[aa].x+=zy[to][0],ant[aa].y+=zy[to][1];
if(ant[aa].x==n&&ant[aa].y==m&&!target)
{
target=aa;
ant[aa].hp=min(ant[aa].hp+2*pow(1.1,ant[aa].level),4*pow(1.1,ant[aa].level));
}
map[ant[aa].x][ant[aa].y].ant=1;
}
void move_ants()
{
int now=fro[0];
while(now)
{
move_an_ant(now);
now=fro[now];
}
}
int if_attack(int aa,int bb)
{
int a=tower[aa].x-ant[bb].x,b=tower[aa].y-ant[bb].y;
a*=a,b*=b;
if(a+b>r*r)return 0;
return a+b;
}
void attack_ants()
{
for(int i=1;i<=s;i++)
{
int now=fro[0],to=0,mn=0x7fffffff;
while(now)
{
int tt=if_attack(i,now);
if(tt)
{
if(tt<mn) mn=tt,to=now;
if(target==now)
{
to=now;
break;
}
}
now=fro[now];
}
if(!to)continue;
int mx=max(tower[i].x,ant[to].x),my=max(tower[i].y,ant[to].y);
int nx=min(tower[i].x,ant[to].x),ny=min(tower[i].y,ant[to].y);
now=fro[0];
int A=tower[i].y-ant[to].y,B=ant[to].x-tower[i].x;
int C=tower[i].x*ant[to].y-tower[i].y*ant[to].x;
double fm=1.0/sqrt(A*A+B*B);
while(now)
{
if(ant[now].x>mx||ant[now].x<nx)
{
now=fro[now];
continue;
}
if(ant[now].y>my||ant[now].y<ny)
{
now=fro[now];
continue;
}
if(fabs(ant[now].x*A+ant[now].y*B+C)*fm<=0.50) ant[now].hp-=d;
now=fro[now];
}
}
}
void find_death()
{
int now=fro[0];
while(now)
{
if(ant[now].hp<0)
{
js--;
fro[pre[now]]=fro[now];
pre[fro[now]]=pre[now];
map[ant[now].x][ant[now].y].ant=0;
if(now==target)target=0;
}
now=fro[now];
}
}
void come_to_end(bool human,int ti)
{
if(human) printf("The game is going on\n");
else printf("Game over after %d seconds\n",ti);
int now=fro[0];
printf("%d\n",js);
while(now)
{
print(now);
now=fro[now];
}
}
void clean_map()
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
if(!map[i][j].inf)continue;
map[i][j].inf--;
}
}
int now=fro[0];
while(now)
{
ant[now].age++;
now=fro[now];
}
}
int main()
{
scanf("%d%d",&n,&m);
scanf("%d%d%d",&s,&d,&r);
for(int i=1;i<=s;i++)
{
scanf("%d%d",&tower[i].x,&tower[i].y);
map[tower[i].x][tower[i].y].tower=1;
}
scanf("%d",&t);
zy[1][0]=0,zy[1][1]=1;
zy[2][0]=1,zy[2][1]=0;
zy[3][0]=0,zy[3][1]=-1;
zy[4][0]=-1,zy[4][1]=0;
for(int i=1;i<=t;i++)
{
born();
stay_information();
move_ants();
attack_ants();
find_death();
if(target&&(!ant[target].x)&&(!ant[target].y))
{
come_to_end(0,i);
exit(0);
}
clean_map();
}
come_to_end(1,0);
return 0;
}
[ZJOI2008]杀蚂蚁antbuster 题解的更多相关文章
- [BZOJ 1033][ZJOI2008]杀蚂蚁antbuster
1033: [ZJOI2008]杀蚂蚁antbuster Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1200 Solved: 507[Submi ...
- [ZJOI2008]杀蚂蚁antbuster
[ZJOI2008]杀蚂蚁antbuster 题目 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试 ...
- 【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster
Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的任 ...
- bzoj千题计划121:bzoj1033: [ZJOI2008]杀蚂蚁antbuster
http://www.lydsy.com/JudgeOnline/problem.php?id=1033 经半个下午+一个晚上+半个晚上 的 昏天黑地调代码 最终成果: codevs.洛谷.tyvj上 ...
- BZOJ1033:[ZJOI2008]杀蚂蚁antbuster(模拟)
Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右 下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的 ...
- [bzoj1033] [ZJOI2008]杀蚂蚁antbuster
Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的任 ...
- 【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster(判断线段是否和圆相交)
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1033 [题意] https://www.zybuluo.com/Jerusalem/n ...
- [BZOJ 1033] [ZJOI2008] 杀蚂蚁antbuster 【模拟!】
题目链接: BZOJ - 1033 题目分析 模拟!纯粹按照题目描述模拟! 这是一道喜闻乐见的经典模拟题! 我一共写了2遍,Debug 历时2天的所有晚自习 ... 时间超过 8h ... 我真是太弱 ...
- BZOJ 1033: [ZJOI2008]杀蚂蚁antbuster(模拟)
坑爹的模拟题QAQ DEBUG多了1kb QAQ 按题意做就行了 注意理解题意啊啊啊啊 尼玛输出忘换行wa了3次QAQ CODE: #include<cstdio>#include< ...
随机推荐
- 字符串、数组操作函数 Copy Concat Delete Insert High MidStr Pos SetLength StrPCopy TrimLeft
对字符串及数组的操作,是每个程序员必须要掌握的.熟练的使用这些函数,在编程时能更加得心应手. 1.Copy 功能说明:该函数用于从字符串中复制指定范围中的字符.该函数有3个参数.第一个参数是数据源(即 ...
- Android动画基础——属性动画(Property Animation)
本篇涉及例子下载:Github 本篇讲android 3.0引入的属性动画框架,上篇写视图动画View Animation时就说过ViewAnimation的缺点,那就是动画作用的是view本身的视觉 ...
- JavaScript语言核心--词法结构
编程语言的词法结构是一套基础性规则,用来描述如何使用这门语言来编写程序.作为语法的基础,它规定了诸如变量名是什么样的.怎么写注释,以及程序语言之间如何分隔等规则. 1. 字符集 JavaScript程 ...
- 一键增加swap空间脚本
#!/bin/bash echo -e "\033[33m Your current swap is \033[0m" free -h mkdir /SwapDir cd /Swa ...
- 今天想安装 windowsl ive 提示安装失败 错误码
Windows Live installation error: OnCatalogResult: 0x80072ee6 看了了这个老兄的回答,试了试,果然OK,谢谢@普洛提亚从这里下载安装包,然后安 ...
- Delphi中,indy控件实现收发邮件的几点学习记录( 可以考虑加入多线程,用多个邮箱做一个邮箱群发器) 转
关于用Delphi中的Indy控件实现收发邮件的几点学习记录 这几天心里颇不宁静,不是因为项目延期,而是因为自己几个月前做的邮件发送程序至今无任何进展,虽然一向谦虚的人在网上发 ...
- 前端开发在手机UC浏览器上遇到的坑
1.user-scalable问题 写手机页面都会加一个meta标签 <meta content="width=device-width, initial-scale=1.0, max ...
- javascript 实现ajax
AJAX 英文名称 Asynchronous JavaScript and XML即异步的 JavaScript 和 XML AJAX 是与服务器交换数据并更新部分网页一门无刷新技术构建自己的ajax ...
- 【图文】[新手]C++ 动态库导出函数名“乱码”及解决
刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...
- Cleanmymac X 4.4.3 激活破解版|兼容mac最新系统-Mac电脑清理工具
CleanMyMac X 4.4.3 激活破解版为最新版清理工具,为你所爱的东西腾出空间.CleanMyMac拥有一系列巧妙的新功能,它可以安全.智能地扫描和清理整个系统,删除大的未使用的文件,卸载不 ...