BZOJ2548 [CTSC2002] 灭鼠行动

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

Description

最近,有一些繁殖力很强的老鼠在下水道非常猖獗,灭鼠特工队正在计划消灭这些老鼠。下水道只有东西方向和南北方向的管道,如图所示。

灭鼠特工队的队员拥有强大的武器。他们将在某些时刻t在某些位置(x,y)放置武器。他们所使用的武器包括:

1.        强力炸弹:它的攻击范围限定在管道内部,是沿竖直和水平方向,离(x,y)的距离不超过L的区域,但是不能穿透下水道壁。它将在放置之后立刻爆炸,且攻击范围内的老鼠将被全部炸死。

2.        神秘射线:它的攻击范围是以(x,y)为圆心,半径为R的圆,而且可以穿透下水道壁。射线在时刻t施放后,将使攻击范围内的所有老鼠立刻陷入昏迷状态,失去知觉,停止一切生理活动,待到第t+3时刻才能恢复(保持失去知觉前的朝向)。如果在昏迷状态中再次受到射线攻击,那么它将再推迟3个时刻恢复。例如,若老鼠在时刻t和时刻t+1个受到一次射线的攻击,则它要昏迷到第t+3+3时刻才能恢复知觉。恢复知觉以后,老鼠将继续以前的生理活动。

3.        定时炸弹:它的攻击范围仅包括(x,y)。它在时刻t放置后,将在第t+3时刻爆炸,爆炸时处在(x,y)点的老鼠将全部被炸死。

4.        生物炸弹:它的攻击范围仅包括(x,y)。它将在放置之后立刻爆炸,使处在(x,y)点的所有老鼠的性别改变(无论大小,雌变成雄,雄变成雌),但不影响老鼠的正常生理活动。

虽然特工队的实力很强,但是老鼠的实力也不容忽视。

我们定义,相邻两个时刻之间是一个时间单位。从t=0时刻开始,每只老鼠就从初始位置向某一初始方向运动。只要前方有管道,如上图中沿方向N到达点A,老鼠就会一直向前走,运动速度为1。否则,如果只有左边或者只有右边有管道,如上图中沿方向E到达点B时,再不能沿原方向继续前进,它就会花费一个时间单位朝该方向原地转动90度,即它将改变方向朝向S。如果它左边和右边都有管道,如上图中沿方向W到达点C,老鼠会回忆这是第几次处于这种情况。如果是第奇数次遇到,它会向左转,第偶数次就向右转。如果它处于一条死路的尽头,如上图中沿方向W到达点D,那么它会花费两个时间单位连续向右转两次,即它将改变方向朝向E。

如果在t时刻某点恰好只有两只老鼠,一只为成年雄老鼠,一只为成年雌老鼠,则它们将会因为进行繁殖而在该点停留两个单位时间,t+2时刻会在该点对每个有管道的方向生出一只朝着该方向的小老鼠,南北方向为雄小老鼠,东西方向为雌小老鼠。如上图中的C点,t时刻恰好只有两只老鼠,它们都已成年且性别相异,那么在第t+2时刻就会在该点生出三只小老鼠,它们分别朝向N、S、E,性别分别是雄性、雄性、雌性。小老鼠一出生就立刻开始移动,而成年老鼠需要再休息一个时间单位,即在t+3时刻继续活动(两只老鼠都保持生育前的朝向)。小老鼠需要成长5个时间单位才会长成为成年老鼠。

特工队现在制定了一套灭鼠计划,其中包括在下水管道放置武器的位置、时间和类型。你需要帮他们计算灭鼠行动的效果,如果在该计划实施的过程中,老鼠的数量超过了某个限定值,就会爆发鼠疫。

Input

第一行为4个整数L R m n(0<=L,R<=10,1<=m,n<=50),其中L代表强力炸弹的有效攻击距离,R代表神秘射线的作用半径,m和n代表下水道平面图的规模。x坐标的范围为[1,m], y坐标的范围为[1,n]。

从第2行到第m+1行为下水道结构图。我们用方向数1代表N(北),用方向数2代表E(东),用方向数4代表S(南),用方向数8代表W(西)。第i+1行的第j个数字ci,j代表点(i,j)处有管道连接的所有方向数之和,如上图中的点B的方向数之和为12。

第m+2行为一个整数K(1<=K<=50),代表时刻0时老鼠的个数(此时老鼠都是成年的)。

第m+3行到第m+K+2行每行描述一只老鼠,包括该老鼠的初始坐标(x,y) (1<=x<=m, 1<=y<=n),朝向(’E’,’S’,’W’,’N’)以及性别(’X’=雄,’Y’=雌)。输入保证每个老鼠都在水管内。

第m+K+3行为两个整数P,Limit(1<=P, Limit<=100),分别表示特工队准备使用的武器个数以及控制鼠疫发生的老鼠数量的极限。

第m+K+4行到第m+K+P+3行每行描述一个武器,包括该武器的类型(1-强力炸弹,2-神秘射线,3-定时炸弹,4-生物炸弹),放置的时刻t(t>=1),放置的坐标(x,y) (1<=x<=m, 1<=y<=n),输入保证武器放置在管道内。武器按照放置的时间不降序排列。

    最后一行包含一个整数Time(1<=Time<=1000),表示模拟的结束时刻。Time保证比所有武器的放置时刻大。

Output

包含一个整数。如果爆发了鼠疫,该整数为-1,否则该整数为时刻Time的老鼠数目。

大模拟什么的最恶心了

难的不是coding,而是debugging

如果你从网上下载到了数据,那么请把第7个点的答案由79改为22

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <cmath>
  6 #define rep(i,l,r) for(int i=l; i<=r; i++)
  7 #define clr(x,y) memset(x,y,sizeof(x))
  8 using namespace std;
  9 const int maxn = 60;
 10 const int bin[4] = {1,2,4,8};
 11 const int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
 12 inline int read(){
 13     int ans = 0, f = 1;
 14     char c = getchar();
 15     for(; !isdigit(c); c = getchar())
 16     if (c == ‘-‘) f = -1;
 17     for(; isdigit(c); c = getchar())
 18     ans = ans * 10 + c - ‘0‘;
 19     return ans * f;
 20 }
 21 struct Mouse{
 22     int x,y,dir,grow,frez,time,breed;
 23     bool sex,dead;
 24 }m[110];
 25 struct Weapon{
 26     int x,y,type,time;
 27 }w[110];
 28 int L,R,M,n,P,K,head=0,cur,limit,Time,c[maxn][maxn],num[maxn][maxn];
 29 bool mark[maxn][maxn];
 30 char ch[10];
 31 inline double getdis(int x1,int y1,int x2,int y2){
 32     return sqrt((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2));
 33 }
 34 inline void flush(){
 35     int cnt = 0;
 36     rep(i,1,K) if (!m[i].dead) m[++cnt] = m[i];
 37     K = cnt;
 38 }
 39 void expose(){
 40     rep(p,1,P){
 41         Weapon now = w[p];
 42         if (now.time == cur)
 43         switch(now.type){
 44             case 1:
 45                 clr(mark,0); mark[now.x][now.y] = 1;
 46                 rep(i,0,3){
 47                     int nowx = now.x, nowy = now.y, dis = 0;
 48                     while (c[nowx][nowy] & bin[i]){
 49                         nowx += dir[i][0]; nowy += dir[i][1]; dis++;
 50                         if (dis > L) break;
 51                         mark[nowx][nowy] = 1;
 52                     }
 53                 }
 54                 rep(i,1,K){
 55                     if (mark[m[i].x][m[i].y]) m[i].dead = 1;
 56                 }
 57             break;
 58             case 2:
 59                 rep(i,1,K){
 60                     if (getdis(now.x,now.y,m[i].x,m[i].y) <= R){
 61                         m[i].frez += 3;
 62                         if (m[i].breed > cur) m[i].breed += 3;
 63                     }
 64                 }
 65             break;
 66             case 3:
 67                 rep(i,1,K)
 68                 if (m[i].x == now.x && m[i].y == now.y)
 69                 m[i].dead = 1;
 70             break;
 71             case 4:
 72                 rep(i,1,K)
 73                 if (m[i].x == now.x && m[i].y == now.y)
 74                 m[i].sex ^= 1;
 75             break;
 76         }
 77     }
 78 }
 79 void breed(){
 80     flush();
 81     clr(num,0);
 82     rep(i,1,K) num[m[i].x][m[i].y]++;
 83     rep(i,1,K){
 84         if (!m[i].grow && !m[i].frez && m[i].breed == -1 && !m[i].sex && num[m[i].x][m[i].y] == 2){
 85             rep(j,1,K) if (!m[j].grow && !m[j].frez && m[j].sex && m[j].x == m[i].x && m[j].y == m[i].y){
 86                 m[i].frez += 3; m[j].frez += 3;
 87                 m[i].breed = m[j].breed = cur + 2;
 88                 break;
 89             }
 90         }
 91     }
 92     rep(i,1,K){
 93         if (m[i].breed == cur && m[i].sex){
 94             rep(j,0,3){
 95                 if (bin[j] & c[m[i].x][m[i].y]){
 96                     K++; m[K].x = m[i].x; m[K].y = m[i].y;
 97                     m[K].frez = m[K].time = m[K].dead = 0;
 98                     m[K].dir = j; m[K].grow = 5; m[K].breed = -1;
 99                     if (j == 0 || j == 2) m[K].sex = 0; else m[K].sex = 1;
100                 }
101             }
102         }
103     }
104 }
105 void move(Mouse &x){
106     x.breed = -1; int now = c[x.x][x.y];
107     if (now & bin[x.dir]){
108         x.x += dir[x.dir][0]; x.y += dir[x.dir][1];
109         return;
110     }
111     int r = (x.dir + 1) % 4, l = (x.dir + 3) % 4, b = (x.dir + 2) % 4;
112     if (now & bin[b]) now -= bin[b];
113     if (!now){
114         x.dir = r; return;
115     }
116     if (now == bin[l]) x.dir = l;
117     else if (now == bin[r]) x.dir = r;
118     else{
119         x.time++;
120         if (x.time & 1) x.dir = l;
121         else x.dir = r;
122     }
123 }
124 int main(){
125     L = read(); R = read(); M = read(); n = read();
126     rep(i,1,M) rep(j,1,n) c[i][j] = read();
127     K = read();
128     rep(i,1,K){
129         m[i].x = read(); m[i].y = read();
130         scanf("%s",ch);
131         if (ch[0] == ‘N‘) m[i].dir = 0; else if (ch[0] == ‘E‘) m[i].dir = 1;
132         else if (ch[0] == ‘S‘) m[i].dir = 2; else if (ch[0] == ‘W‘) m[i].dir = 3;
133         scanf("%s",ch); m[i].sex = (ch[0] == ‘Y‘);
134         m[i].breed = -1;
135     }
136     P = read(); limit = read();
137     rep(i,1,P){
138         w[i].type = read(); w[i].time = read(); w[i].x = read(); w[i].y = read();
139         if (w[i].type == 3) w[i].time += 3;
140     }
141     Time = read();
142     for(cur=0; cur<=Time; cur++){
143         expose();
144         breed();
145         if (K > limit){
146             printf("-1\n"); return 0;
147         }
148         if (cur != Time){
149             rep(i,1,K)
150             if (m[i].frez) m[i].frez--;
151             else{
152                 move(m[i]);
153                 if (m[i].grow) m[i].grow--;
154             }
155         }
156     }
157     printf("%d\n",K);
158     return 0;
159 }

时间: 2024-10-21 18:15:27

BZOJ2548 [CTSC2002] 灭鼠行动的相关文章

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

[Bzoj 2547] [Ctsc2002] 玩具兵

2547: [Ctsc2002]玩具兵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 317  Solved: 152[Submit][Status][Discuss] Description 小明的爸爸给他买了一盒玩具兵,其中有 K个步兵,K个骑兵和一个天兵,个个高大威猛,形象逼真.盒子里还有一个M*N棋盘,每个格子(i,j)都有一个高度Hij,并且大得足以容纳所有的玩具兵.小明把所有的玩具兵都放到棋盘上去,突然想到了一种很有趣的玩法:任意挑选

bzoj2547: [Ctsc2002]玩具兵

划了一天水,其实我还是有点愧疚的. 传送门 其实是水题,然而我真是太蠢了... 首先不考虑天兵,其他兵要到一个点去一定是通过它-另一种兵-它--这样多次交换的,并且交换对象是无所谓的,和它换的兵最终会是在原位置. 而且骑兵和步兵的数量相等,就不存在一个兵找不到人跟它换的情况,那么一个确定的方案下换的次数最多的兵换的次数就是答案. 先spfa找出每个兵到每个位置的最小换的次数,然后二分答案,把每个兵向它可以到的地方连边,跑最大匹配,考虑到还有天兵,而天兵是可以一步登天的超神存在,所以如果最大匹配数

做衡八的日子(转自VFleaking)

随着我A掉了1149,衡八的第二页也就被我干掉了一半,我的做题进度向第二页的后半页挺进. 想起去年八月的NOI给我的那个沉痛的打击,我至今仍感慨万分.一直以来,小学老师.初中老师总在要我们写一些大谈成功的文章,可是在我参加NOI之前,我根本没有真正悟出我在作文中论述的东西.是那次NOI告诉我,信息学不是什么酱油学科,那群高中生们比我考得好,并不是因为我运气不好,而是因为他们每天都在做题,而我则在研究一些其他的东西.不认真地打酱油,可以拿NOIP一等奖,可以进省队,但是绝对瞒不过NOI的火眼精金.

OSChina 周二乱弹 —— 程序员如何转行卖烧烤

9月8日,星期二,上了一天班,还有四天班,还没算加班,想想心就累,各位 OSCer 你们还好吗? @熊二: 有一天一个程序员见到了上帝.上帝: 小伙子,我可以满足你一个愿望.程序员: 我希望中国国家队能再次打进世界杯.上帝: 这个啊!这个不好办啊,你还说下一个吧!程序员: 那好!我的下一个愿望是每天都能休息6个小时以上.上帝: 还是让中国国家打进世界杯吧... @wht248:哎,堵死了,半天车没动 上班的兴趣已消磨殆尽! @涉水轻舟:这话说的,好像上班了就不穷一样- 穷自己也就算了,有的盆友竟

豆奶怎么做好吃 豆奶的营养价值

[导读]豆奶是我们日常中都会食用的一种饮品.豆奶中含有丰富的蛋白质,且口感润滑深受大家的喜爱,不过你知道豆奶是怎么做的吗?豆奶怎么做才好吃呢?跟着小编一起来看看吧. 豆奶怎么做好吃 要知道,自己制作的豆奶口感润滑,具有多种功效,十分适合早餐食用.那么,豆奶怎么做? 食材主料 :黄豆30g ,花生20g. 辅料: 核桃.水. 牛奶200ml. 步骤 1.花生和黄豆提前泡发. 2.用开水烫一下,剥去外皮. 3.核桃用开水烫一下. 4.同样剥去外皮. 5.将核桃花生黄豆放入豆浆机内. 6.选择果蔬冷饮

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ

zoj5341 捕老鼠

Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕老鼠. 猫虽然擅长捕老鼠,但是老鼠们太健美了,身手敏捷,于是猫想到了一个绝妙的办法:它决定点燃纯艾条,用烟熏老鼠. 农夫约的农庄里有N 个仓库,排成了一排,编号为1-N. 假设猫在第i 个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散Ai的距离,接着所有|i-j|<=Ai 的仓库j 的老鼠被消灭. 猫是一只爱护空气环境的好猫,它希望知道最少需要多少支艾条,才可以

通辽市神鹰通用航空

通辽市神鹰通用航空有限公司(简称:神鹰航空)始建于1999年,注册资本金5200万元,是我国目前最大的民营通用航空公司之一,也是中国民航总局最早审批的通用航空甲类企业,下设航务运行部.机务工程部.综合管理部.财务部.采购部.飞行培训中心.市场营销部.安全监察部八个职能部门,拥有一只素质高.业务精.能力强的专业精英队伍.公司目前拥有各类飞机30余架,在职员工79人.其中,大学本科以上学历的专业人员占员工总数的60%以上.企业采用现代管理模式,制定严谨的管理机制对企业进行管理.公司主要开展飞机灭虫.