The "endless" model in "I, zombie" of "Plants vs. Zombies" is my favourite. The aim of the game is to put down the zombies most reasonable in the right-most , to eat the brain protected by Plants in the left-most.To simplify the problem ,we provide only one kind of Zombies : normal Zombies with 50 hp each. The map contains one row only, and we provide two kinds of plants : Peashooter (with 10hp) and Potato Mine. The operating steps of every second are as below(Warning: make sure your program strictly follow the order of these steps):
1.Put some or none zombies in the right-most grid one by one. (In the right grid of the right-most plant at beginning). 2.Judge every survived zombie, whether he's standing on a grid with a Peashooter.     2.1.If it's true, he attacks the Peashooter in his grid, and the Peashooter decreases 1 hp. The Peashooter's hp may be negative at that moment, but it's still alive!     2.2.If it's false, he moves left for one grid. 3.If there are still some zombies in the map, every survived Peashooter will shoot a pea to the zombie who was put earliest. (the zombie's hp decreases 1 hp for each pea, the zombie's hp can be negative at that moment, but it's still alive!) 4.If there are zombies in the grids where Potato Mine stands , then the Potato Mine explodes , all the zombies' hp in this grid become 0. 5.The plants and zombies with non-positive hp disappear(until now they are dead).
Now, given the map, you are to tell me how many zombies are needed at least, in order to eat the brain in the left-most?
 
Input
The first line is a number T (1<=T<=100), represents the number of cases. The next T line with n(0<n<=100) characters ,represents each case ,'P' represents Peashooters ,'M' represents Potato Mine ,no other character in the input.
 
Output
Output a number represents the minimum zombies needed to eat the brain in the left-most. Following the case number (start with 1).
 
Sample Input
5
PM
PP
PPP
MMMMM
PPMM
 
Sample Output
Case 1: 2
Case 2: 1
Case 3: 2
Case 4: 6
Case 5: 3
 
题意:模拟植物大战僵尸,地图只有一行,有两种植物:豌豆射手(P)和炸弹土豆(M),僵尸要进攻,每只僵尸的hp是50,每个豌豆射手的hp是10,
僵尸如果走在土豆上,土豆会爆炸,所有在土豆处的僵尸hp都变为0,如果僵尸走在豌豆射手处,则每只僵尸对豌豆射手攻击一次,造成1点的伤害,
豌豆射手会攻击走在最前面的僵尸,每个豌豆射手攻击一次,造成1点的伤害。问最少需要多少只僵尸才能赢。
 
解析:很恶心的模拟,要注意的是僵尸不是一个接着一个排成队放在右边,可以几个僵尸放在同一个位置开始进攻,不然如果一开始就有超过50个
豌豆射手,那岂不是进来一个死一个(我最开始以为是一个一个放,以为不会有这种无解的情况。。。。。。),如果僵尸碰到的是炸弹,那么下一
回合可以认为僵尸的最左位置为炸弹的左边。如果碰到的不是炸弹,则不停向左统计植物个数,直到遇到第一个炸弹,然后二分可以吃掉这些植物
的最少僵尸个数。详见代码实现。
 
代码
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
const int maxn=;
char S[maxn];
int L,Pnum,Mnum,step;
void init()
{
L=strlen(S)-;
Pnum=Mnum=; //豌豆射手与土豆的个数
for(int i=;i<=L;i++)
if(S[i]=='P') Pnum++;
else Mnum++;
}
bool judge(int totpnum,int pnum,int znum)
{
int nowstep=step;
int P_hp=,Z_hp=; //豌豆射手和僵尸的hp
while(pnum>&&znum>)
{
if(nowstep>){ nowstep--; Z_hp-=totpnum; } //没走到豌豆射手处
else{ P_hp-=znum; Z_hp-=totpnum; } //走到了两个都要受伤害
if(P_hp<=) //死一个射手
{
P_hp=;
totpnum--; pnum--;
nowstep=;
}
if(Z_hp<=){ Z_hp=; znum--; } //死一个僵尸
}
if(pnum<=&&znum>) return true; //所有豌豆射手挂掉而僵尸有多的
return false;
}
int BIS(int totpnum,int pnum) //二分
{
int x=,y=*maxn,mid;
while(x<=y)
{
mid=(x+y)/;
if(judge(totpnum,pnum,mid)) y=mid-;
else x=mid+;
}
return y+;
}
int solve()
{
int ret=; //ret是需要的僵尸的个数
if(S[L]=='M') { ret++; L--; step=; } //最右边是土豆,step代表走到下一个位置需要的步数
else step=;
while(L>=) //知道小于0才算赢
{
if(S[L]=='M') //是土豆
{
if(step>) //往前走
{
step--;
if(Pnum>=) ret++; //超过50个豌豆射手死一个僵尸
continue;
}
else ret++; //炸死一个
Mnum--; L--;
step=; //step变为2
}
else //如果是豌豆射手
{
int pnum=;
for(int i=L;i>=;i--) //一直到找到土豆
if(S[i]=='M') break;
else pnum++;
ret+=BIS(Pnum,pnum); //二分得到最小的僵尸个数
Pnum-=pnum;
L-=pnum+; //多减1表示把土豆算进去了,因为有没死的僵尸在土豆处牺牲
step=;
}
}
if(S[]=='M') ret++; //如果最左边是土豆,则还需要一个僵尸去攻击首脑
return ret;
}
int main()
{
int T,Case=;
scanf("%d",&T);
while(T--)
{
scanf("%s",S); //植物
init();
printf("Case %d: %d\n",++Case,solve());
}
return ;
}

Hdu3640-I, zombie(模拟+二分)的更多相关文章

  1. FZU 1575 小学生的游戏【模拟二分】

    某天,无聊的小斌叫上几个同学玩游戏,其中有比较笨的小兴,比较傻的小雪,可爱的小霞和自以为是的小楠.他们去找聪明的小明去给他们当裁判.判定谁取得游戏胜利. 而这个游戏是由小斌想个1到10000000的数 ...

  2. Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) A B C D 水 模拟 二分 贪心

    A. Is it rated? time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  3. UVALive 3971 Assemble(模拟 + 二分)

    UVALive 3971 题意:有b块钱.想要组装一台电脑,给出n个配件的种类,名字,价格,品质因子.若各种类配件各买一个,总价格<=b,求最差品质配件的最大品质因子. 思路: 求最大的最小值一 ...

  4. bzoj4717 改装 模拟+二分

    Description [题目背景] 小Q最近喜欢上了一款游戏,名为<舰队connection>,在游戏中,小Q指挥强大的舰队南征北战,从而成为了一名dalao.在游戏中,不仅船只能力很重 ...

  5. Largest Allowed Area【模拟+二分】

    Largest Allowed Area 题目链接(点击) 题目描述 A company is looking for land to build its headquarters. It has a ...

  6. Codeforces Round #481 (Div. 3) C. Letters (模拟,二分)

    题意:有个\(n\)个公寓,每个公寓\(a_{i}\)代表着编号为\(1-a_{i}\)个房间,给你房间号,问它在第几栋公寓的第几个房间. 题解:对每个公寓的房间号记一个前缀和,二分查找属于第几个公寓 ...

  7. 模拟+二分 poj-1019-Number Sequence

    题目链接: http://poj.org/problem?id=1019 题目大意: Sk表示123...k 把S1S2S3...Sk排成一行 比如:112123123412345123456.... ...

  8. Codeforces 404E: Maze 1D(二分)

    题意:指令“R”机器人会向右走一步,“L”是向左.起初机器人在0位置,可以在除了0以外的任何位置放障碍,如果机器人的指令将使它走到障碍上,那这一步他会保持不动.要求让机器人最终结束的那一步一定只走过一 ...

  9. NOIP模拟测试7

    期望得分:60+60+60 实际得分:60+60+0 这次考试主要是T3搜索打挂了(我可是靠搜索吃饭的); 1.数组开小了,不过开大数组只拿到了10分的好成绩. 2.题意没审清(其实是他没说清). 以 ...

随机推荐

  1. [置顶] API相关工作过往的总结之Sandcastle简要使用介绍

    Sandcastle介绍 在微软推出Sandcastle之前,人们倾向于选择开源的NDoc(.NET代码文档生成器).NDo可以将 C#.NET 编译生成的程序集和对应的 /doc XML文档,自动转 ...

  2. 合并多个excel工作簿

    合并多个Excel工作簿,会出现电话号码以科学计数法显示,如果想要以字符串方式处理,要按如下完整代码 public static void mergeWorkBook() throws Excepti ...

  3. 利用libevent的timer实现定时器interval

    在不怎么了解libevent的情况下,看到timer这个关键字想到可以用来做定时任务,官方资料也不齐全,就从代码里看到了TIMEOUT字样,这么说来应该是支持timeout了,那interval呢,貌 ...

  4. hadoop2对比hadoop1

    hadoop2对比hadoop1 1.体系结构 HDFS+MapReduce,共同点都是分布式的,主从关系结构. HDFS=一个NameNode+多个DataNode, NameNode含有我们用户存 ...

  5. bat处理文件

    bat处理文件 作用:可以一次性执行多个命令的文件. 为什么要学bat处理文件? 快速运行一个软件一般都会把软件打包一个jar包,但是jar双击可以运行仅对图形化界面的软件起作用,对于控制台的程序是不 ...

  6. Stm32高级定时器(四)

    Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...

  7. MySql Update Select 嵌套

    UPDATE `TB_CM_Dic` SET `ParentID` = (SELECT `ID` FROM (SELECT * FROM `TB_CM_Dic`) AS B WHERE `DicNam ...

  8. React初步

    今天整理一下自己关于react的学习笔记. 什么是React? 学习某一个框架首先得知道这个框架是干什么的,它的特点是什么,有哪些优点和缺点. React有4个特点 组件化 虚拟DOM 单项数据流 j ...

  9. c#转码解码

    ///反转码                          mdata[k].MNAME = unescape(mdata[k].MNAME);程家楠 13:51:00 Microsoft.JSc ...

  10. Android-------------获取手机IP地址

    ##帮助类PhoneNetStateUtil package com.funs.PhoneIPAddress.utils; /**      * 手机联网状态工具类 需要的权限 WIFI时:</ ...