【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1033

【题意】



https://www.zybuluo.com/Jerusalem/note/221811

【题解】



。。。

模拟题。

要用到计算几何知识;

即求一段线段是不是和圆相交;

如果一只蚂蚁被打死了.还要一直打才行。

因为有一个蛋糕蚂蚁的判断。。



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x) typedef pair<int, int> pii;
typedef pair<LL, LL> pll; const int dx[9] = { 0,0,1,0,-1,-1,-1,1,1 };
const int dy[9] = { 0,1,0,-1,0,-1,1,-1,1 };
const double pi = acos(-1.0);
const int MAX_PAOTA = 25;
const int MAX_MAYI = 10;
const int MAX_SIZE = 10; struct point
{
int x, y;
}; struct mayi
{
int x, y, id, xue, cunzai, dangao, prex, prey, age, chushi;
void get_xue(int k)
{
k = ((k - 1) / 6) + 1;//通过id获取它的等级
double t = 1;
rep1(i, 1, k)
t = t*1.1;//计算1.1的k次方
t *= 4;//乘上4
xue = int(t);//转成整数
chushi = xue;//记录初始血量
}
}; int n, m, s, d, r, tot, now, t;//n和m是地图的长和宽
int tu[MAX_SIZE][MAX_SIZE];
//tot是当前出生的蚂蚁的新id
//now是蚂蚁的只数
point paota[MAX_PAOTA];
mayi mayis[MAX_MAYI];
int can[MAX_SIZE][MAX_SIZE];
int get_dangao; bool cmp1(mayi a, mayi b)//按照出生的顺序排
{
return a.id < b.id;
} bool cmp2(mayi a, mayi b)//按年龄递减排
{
return a.age > b.age;
} void in()
{
rei(n), rei(m);
rei(s), rei(d), rei(r);
rep1(i, 1, s)
{
rei(paota[i].x), rei(paota[i].y);
can[paota[i].x][paota[i].y] = 0;
}
rei(t);
} int kong()
{
rep1(i, 1, 6)
if (mayis[i].cunzai == 0)
return i;
return 233;
} void xinxi()
{
rep1(i, 1, 6)
if (mayis[i].cunzai)//如果有蚂蚁
{
int x = mayis[i].x, y = mayis[i].y;//
if (mayis[i].dangao)//如果这只蚂蚁身上有蛋糕就信息素加5
tu[x][y] += 5;
else//否则加2
tu[x][y] += 2;
}
} bool is(int x, int y)//判断这个点是不是蛋糕所在的点
{
return (x == n && y == m);
} int sqr(int x)
{
return x*x;
} void moni()
{
rep1(i, 1, 6)//一开始所有的蚂蚁都不存在
mayis[i].cunzai = 0;
get_dangao = 0;
rep1(T, 1, t)
{
if (now < 6 && can[0][0])//如果蚂蚁的个数小于6且蚂蚁窝的位置没有蚂蚁
{
now++;//增加一只蚂蚁
int po = kong();//找到可以新加蚂蚁的蚂蚁数组的下标
mayis[po].x = mayis[po].y = 0, mayis[po].cunzai = 1;//把这个蚂蚁加入
//记录坐标为0,0然后标记这只蚂蚁存在
mayis[po].id = ++tot, mayis[po].get_xue(tot), mayis[po].dangao = 0;
mayis[po].prex = mayis[po].prey = -1;
//tot是这只蚂蚁的id,即总共是第几只蚂蚁,通过这个tot能获得它的血量,然后一开始都没有蛋糕
mayis[po].age = 0;//一开始蚂蚁的年龄是0
can[0][0] = 0;//标记蚂蚁窝的位置有蚂蚁了
}
xinxi();//撒完信息素
//然后呢...然后移动
sort(mayis + 1, mayis + 1 + 6, cmp1);
//id小的先移动
rep1(i, 1, 6)
if (mayis[i].cunzai)//存在就可以移动
{
int tot = 0;
int x = mayis[i].x, y = mayis[i].y, cnt = 0, maxxinxi, cntju;
int tarx, tary;
rep1(j, 1, 4)//先往4个方向找,看看有没有可以走的点
{
int tx = x + dx[j], ty = y + dy[j];
if (tx<0 || tx>n) continue;
if (ty<0 || ty>m) continue;
if (tx == mayis[i].prex && ty == mayis[i].prey) continue;//不能是它之前待的位置
if (!can[tx][ty]) continue;
if (cnt == 0)//顺便找信息素最大的方向
{
maxxinxi = tu[tx][ty];
cntju = j;//记录信息素最大的方向
cnt = 1;//记录只有一个
}
else
{
if (maxxinxi < tu[tx][ty])//如果信息素更大就更新
{
maxxinxi = tu[tx][ty];//
cntju = j;
cnt = 1;
}
else
if (maxxinxi == tu[tx][ty])//如果和最大的信息素一样就增加最大信息素的方向个数
cnt++;
}
tarx = tx, tary = ty;//这是用于处理只有一个方向可以走的情况
tot += can[tx][ty];//记录有几个方向可以走
}
if (tot == 0)//如果没有可以走的点.那就只能待在原地了
//此时是5的倍数也无所谓了
{
mayis[i].prex = x, mayis[i].prey = y;
if (!get_dangao && is(x, y))//可能有蛋糕此时回到了n,m的位置
{
get_dangao = 1;//获得蛋糕
mayis[i].xue += int(mayis[i].chushi / 2);//增加血量
mayis[i].xue = min(mayis[i].xue, mayis[i].chushi);//不能超过上限
mayis[i].dangao = 1;//记录它获得蛋糕
}
}
else
if (tot == 1)//如果只有一个确认的方向可以走
//那么就算是5的倍数也是只能走这个方向
{
mayis[i].prex = x, mayis[i].prey = y;
can[x][y] = 1;//因为已经走开了,所以这个位置就可以走了
mayis[i].x = tarx, mayis[i].y = tary;//到了新的位置
if (!get_dangao && is(tarx, tary))//如果还没有蚂蚁拿到蛋糕且它在蛋糕位置
{
get_dangao = 1;//记录它拿到了蛋糕
mayis[i].xue += int(mayis[i].chushi / 2);//增加血量
mayis[i].xue = min(mayis[i].xue, mayis[i].chushi);//不能超过上限
mayis[i].dangao = 1;//记录它拿到了蛋糕
}
can[tarx][tary] = 0;//这个位置不能再走了
}
else//有多个方向可以走
{
if (cnt == 1)//如果信息量最多的那个只有一个
{
//那么方向就确定了即cntju
//这个时候如果是5的倍数就逆时针旋转
if (((mayis[i].age + 1) % 5) == 0)
{
while (1)
{
cntju--;
if (cntju < 1) cntju = 4;
int tx = x + dx[cntju], ty = y + dy[cntju];
if (tx<0 || tx>n) continue;
if (ty<0 || ty>m) continue;
if ((tx == mayis[i].prex) && (ty == mayis[i].prey)) continue;
if (!can[tx][ty]) continue;
//找到第一个可以走的方向
break;
}
}
//转到了那个合适的位置了
mayis[i].prex = x, mayis[i].prey = y;
can[x][y] = 1;//走开了
mayis[i].x = x + dx[cntju], mayis[i].y = y + dy[cntju];//新的位置
if (!get_dangao && is(mayis[i].x, mayis[i].y))
{
get_dangao = 1;
mayis[i].xue += int(mayis[i].chushi / 2);
mayis[i].xue = min(mayis[i].xue, mayis[i].chushi);
mayis[i].dangao = 1;
}
can[x + dx[cntju]][y + dy[cntju]] = 0;//这个位置不能走了
}
else
{
//信息素没办法判断了
//先从正东然后 顺时针旋转转到第一个可以选择的地方
rep1(j, 1, 4)
{
int tx = x + dx[j], ty = y + dy[j];
if (tx<0 || tx>n) continue;
if (ty<0 || ty>m) continue;
if ((tx == mayis[i].prex) && (ty == mayis[i].prey)) continue;
if (!can[tx][ty]) continue;
if (tu[tx][ty] != maxxinxi) continue;//信息素不是最大的那个不算的。。
cntju = j;
break;
}
if (((mayis[i].age + 1) % 5) == 0)//这个时候如果是5的倍数就逆时针旋转
{
while (1)
{
cntju--;
if (cntju < 1) cntju = 4;
int tx = x + dx[cntju], ty = y + dy[cntju];
if (tx<0 || tx>n) continue;
if (ty<0 || ty>m) continue;
if ((tx == mayis[i].prex) && (ty == mayis[i].prey)) continue;
if (!can[tx][ty]) continue;
break;
}
}
mayis[i].prex = x, mayis[i].prey = y;
can[x][y] = 1;//可以走了
mayis[i].x = x + dx[cntju], mayis[i].y = y + dy[cntju];//到了新位置
if (!get_dangao && is(mayis[i].x, mayis[i].y))//到了蛋糕位置,蛋糕没被拿走
{
get_dangao = 1;
mayis[i].xue += int(mayis[i].chushi / 2);
mayis[i].xue = min(mayis[i].xue, mayis[i].chushi);
mayis[i].dangao = 1;
}
can[x + dx[cntju]][y + dy[cntju]] = 0;//不能走了
}
}
}
//蚂蚁都移动完了.塔开始攻击
rep1(i, 1, s)
{//i枚举每一个塔
int which = -1, midis = -1;
rep1(j, 1, 6)//如果有这只蚂蚁
if (mayis[j].cunzai)
{
int x = mayis[j].x, y = mayis[j].y;
int dis = sqr(x - paota[i].x) + sqr(y - paota[i].y);//获取距离平方
if (dis <= sqr(r))//如果在攻击范围内
{
if (mayis[j].dangao)//如果是拿着蛋糕的那只,就直接攻击它了
{
which = j;
midis = dis;
break;
}
if (midis == -1)//否则选择距离最近的那只搞
{
midis = dis;
which = j;
}
else
{
if (dis < midis)
{
midis = dis;
which = j;
}
}
}
}
if (which == -1) continue;//没有一直蚂蚁能攻击到就跳过
int x = mayis[which].x - paota[i].x, y = mayis[which].y - paota[i].y;
int MXX = max(mayis[which].x, paota[i].x), tpx = min(mayis[which].x, paota[i].x);
int MXY = max(mayis[which].y, paota[i].y), tpy = min(mayis[which].y, paota[i].y); rep1(j, 1, 6)//
if (mayis[j].cunzai)//不要忘记判断这只蚂蚁是否存在
if (mayis[j].x >= tpx&&mayis[j].x <= MXX&&mayis[j].y >= tpy&&mayis[j].y <= MXY
&&fabs((mayis[j].x - paota[i].x)*y - (mayis[j].y - paota[i].y)*x) / sqrt(x*x + y*y) <= 0.5)
mayis[j].xue -= d; }
//攻击也完啦!
rep1(j, 1, 6)
if (mayis[j].cunzai)
{
if (mayis[j].xue < 0)
{
mayis[j].cunzai = 0;
if (mayis[j].dangao)
get_dangao = 0;
can[mayis[j].x][mayis[j].y] = 1;
now--;
}
} //printf("%d\n", get_dangao);
if (get_dangao != 0)
{
//如果拿着蛋糕的那只到了蚂蚁窝就结束啦
rep1(j, 1, 6)
if (mayis[j].cunzai && mayis[j].dangao&& mayis[j].x == 0 && mayis[j].y == 0)
{
printf("Game over after %d seconds\n", T);
return;
}
}
rep1(i, 0, n)
rep1(j, 0, m)
if (tu[i][j] > 0)
tu[i][j]--;
rep1(i, 1, 6)
if (mayis[i].cunzai)
{
mayis[i].age++;
}
//if (T == 7)
// break;
}
printf("The game is going on\n");
} void pre()
{
rep1(i, 0, 9)
rep1(j, 0, 9)
can[i][j] = 1;
} void o()
{
sort(mayis + 1, mayis + 1 + 6, cmp2);
printf("%d\n", now);
rep1(i, 1, 6)
if (mayis[i].cunzai)
cout << mayis[i].age << ' ' << ((mayis[i].id - 1) / 6) + 1 << ' ' << mayis[i].xue << ' ' << mayis[i].x << ' ' << mayis[i].y << endl;
} int main()
{
//printf("%f\n", d_zx(point{ 0,1 }, point{ 1,0 }, point{ 0,0 }));
//return 0;
//freopen("F:\\rush.txt", "r", stdin);
pre();
in();
moni();
o();
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}


【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster(判断线段是否和圆相交)的更多相关文章

  1. [BZOJ 1033][ZJOI2008]杀蚂蚁antbuster

    1033: [ZJOI2008]杀蚂蚁antbuster Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1200  Solved: 507[Submi ...

  2. [BZOJ 1033] [ZJOI2008] 杀蚂蚁antbuster 【模拟!】

    题目链接: BZOJ - 1033 题目分析 模拟!纯粹按照题目描述模拟! 这是一道喜闻乐见的经典模拟题! 我一共写了2遍,Debug 历时2天的所有晚自习 ... 时间超过 8h ... 我真是太弱 ...

  3. BZOJ 1033: [ZJOI2008]杀蚂蚁antbuster(模拟)

    坑爹的模拟题QAQ DEBUG多了1kb QAQ 按题意做就行了 注意理解题意啊啊啊啊 尼玛输出忘换行wa了3次QAQ CODE: #include<cstdio>#include< ...

  4. [ZJOI2008]杀蚂蚁antbuster

    [ZJOI2008]杀蚂蚁antbuster 题目 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试 ...

  5. 【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster

    Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的任 ...

  6. bzoj千题计划121:bzoj1033: [ZJOI2008]杀蚂蚁antbuster

    http://www.lydsy.com/JudgeOnline/problem.php?id=1033 经半个下午+一个晚上+半个晚上 的 昏天黑地调代码 最终成果: codevs.洛谷.tyvj上 ...

  7. BZOJ1033:[ZJOI2008]杀蚂蚁antbuster(模拟)

    Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右 下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的 ...

  8. [bzoj1033] [ZJOI2008]杀蚂蚁antbuster

    Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的任 ...

  9. [ZJOI2008]杀蚂蚁antbuster 题解

    一个题目的可读版本:https://www.zybuluo.com/Jerusalem/note/221811 这两天做的又一道大模拟题,感觉这玩意有毒,会上瘾啊…… 比起猪国杀这道题真心不知道高到哪 ...

随机推荐

  1. Hibernate3.5.4---java application的xml和annotation环境搭建(hibernate.cfg.xml配置文件说明,映射文件Student.hbm.xml说明

    http://blog.csdn.net/centre10/article/details/6050466 来自于:http://blog.csdn.net/centre10/article/deta ...

  2. FarPoint.Win.Spread 常规操作

    FarPoint.Win.Spread.FpSpread fSpread = new FarPoint.Win.Spread.FpSpread();             //设置 行数.列数    ...

  3. amazeui学习笔记--css(HTML元素2)--代码Code

    amazeui学习笔记--css(HTML元素2)--代码Code 一.总结 1.行内代码:code标签<code> 2.代码片段:pre标签<pre> 3.限制代码块高度:添 ...

  4. 【CS Round #48 (Div. 2 only)】Dominant Free Sets

    [链接]h在这里写链接 [题意] 让你在n个点组成的集合里面选取不为空的集合s. 使得这里面的点没有出现某个点a和b,ax>=bx且ay>=by; 问你s的个数. [题解] 我们把这些点按 ...

  5. [React] Close the menu component when click outside the menu

    Most of the time, your components respond to events that occur within the component tree by defining ...

  6. jQuery常用的API

    1.jQuery给标签添加子元素(父子关系) jQuery对象.append("子"); 将div标签插入到ul标签之后 $("ul").append($('d ...

  7. C语言18个经典问题答录

    原文地址:转载:C语言18个经典问题答录作者:lloo 1.这样的初始化有什么问题?char *p = malloc(10); 编译器提示"非法初始式" 云云. 答:这个声明是静态 ...

  8. python2.7一步步实现键盘和鼠标检测

    由于现在python3的pyHook库还没有很完善: 所以选择了python2.7版本 关于环境的搭建 python2.7 用的是anaconda,直接去官网下载去安装就好用,不需要配置环境变量的, ...

  9. ZOJ 3171 The Hidden 7's DP

    传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3203 题目大意给定一串字符串,需要计算出seven的个数. #incl ...

  10. 3、Pycharm使用

    1.设置文件模板 file->settings->Editor->File and Code Templates->Python Script 2.运行 a.点击要运行的文件, ...