【HDU 3640】I, zombie (二分)

传送门

题目描述

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?

题目翻译

现在有一排植物,你可以每一秒从最右边的位置放一个僵尸。

每一秒:

1)在右侧可以放一个或多个僵尸。

2)如果一个僵尸在豌豆射手上,那么那个豌豆射手-1HP(就算是负的还算活),否则向前走一步。

3)如果地图上有僵尸,那么最先放上去的僵尸-1HP(但是还活着)。

4)如果有僵尸踩在土豆雷上,那么这一格上的僵尸HP=0。

5)清除掉没血的植物和僵尸。

现在问你至少需要多少只僵尸来吃掉所有的大脑。

解题思路

我们从贪心的角度入手,一旦遇到土豆雷,最好是只有一个僵尸踩上去,不然会死好多僵尸。并且我们一定要利用到前面的僵尸来挡子弹,每次遇到土豆雷的最好情况是只有一个被炸死,但是这只僵尸身后可以有很多僵尸,这样就不需要每次都从右边走到左边来浪费血了。

我们再来分析具体情况,如果一个僵尸被土豆雷炸死了,那么他后面的僵尸应该要走两步才能到达前面的植物,我们不妨分段处理,每次遇到土豆雷停下,然后处理连着的一段豌豆射手,这样会好分析一些。

如果有一排连续的豌豆射手,这个时候怎么算呢?  二分就可以(但是蒟蒻觉得应该可以直接推出公式qwq)。

注意每次僵尸到植物的距离,如果僵尸还有一格到达豌豆,那么如果总植物的个数比50大的话,就要牺牲一只僵尸。

注意处理一下最前面和最后面的土豆雷,最后的雷会炸死一只,但是还要再放一只,才能吃到脑子。

代码

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int T,len,step,P,ans;
 5 char ch[200];
 6 inline int check(int tot_plant,int int_plant,int z){
 7     int step1=step,plant=10,zombie=50;
 8     while(int_plant>0&&z>0){
 9         if(step1)zombie-=tot_plant,step1--;
10         else plant-=z,zombie-=tot_plant;
11         if(zombie<=0)zombie=50,z--;
12         if(plant<=0)plant=10,tot_plant--,int_plant--,step1=1;
13     }
14     if(int_plant<=0&&z>0)return 1;
15     return 0;
16 }
17 int main(){
18     cin>>T;
19     for(register int t=1;t<=T;t++){
20         scanf("%s",ch);
21         len=strlen(ch)-1;
22         ans=P=step=0;
23         for(register int i=0;i<=len;i++)
24             if(ch[i]==‘P‘)P++;
25         if(ch[len]==‘M‘)ans++,len--,step=2;
26         else step=1;
27         while(len>=0){
28             if(ch[len]==‘M‘){
29                 if(step==2){
30                     step--;
31                     if(P>=50)ans++;
32                     continue;
33                 }
34                 ans++,step=2,len--;
35             }
36             else {
37                 int int_plant=0;
38                 for(register int i=len;i>=0&&ch[i]==‘P‘;i--)int_plant++;
39                 register int l=0,r=400,m;
40                 while(l<r){
41                     m=(l+r)>>1;
42                     if(check(P,int_plant,m))r=m;
43                     else l=m+1;
44                 }
45                 ans+=l,P-=int_plant,len=len-(int_plant+1),step=2;
46             }
47         }
48         if(ch[0]==‘M‘)ans++;
49         printf("Case %d: %d\n",t,ans);
50     }
51 }

原文地址:https://www.cnblogs.com/Fang-Hao/p/9164214.html

时间: 2024-07-30 22:12:32

【HDU 3640】I, zombie (二分)的相关文章

hdu 4185 Oil Skimming(二分匹配)

Oil Skimming Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 883    Accepted Submission(s): 374 Problem Description Thanks to a certain "green" resources company, there is a new profitable

HDU 4417 划分树+二分

题意:有n个数,m个询问(l,r,k),问在区间[l,r] 有多少个数小于等于k. 划分树--查找区间第k大的数.... 利用划分树的性质,二分查找在区间[l,r]小于等于k的个数. 如果在区间第 i 大的数tmp>k,则往下找,如果tmp<k,往上找. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #incl

HDU 1281 棋盘游戏(二分匹配 与 删边)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 根据题目描述,什么是重要点?在求出最大匹配后,进行枚举,依次删边,看最大匹配数会不会发生改变,改变的话,那么该点就是重要点. #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <

HDU 2119 Matrix 简单二分匹配

行做x集,列做y集,1就给该行该列连一条边,输出最大匹配边即可 #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<set> using namespace std; #define N 105 int lef[N], pn;//lef[v]表示Y集的点v 当前连接的点 , pn为x点集的

HDU 3036 拆点二分最大流

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 584    Accepted Submission(s): 117 Problem Description R's girl friend D is on military training somewhere near Harbin. She feels bad ever

HDU 1083 裸的二分匹配

Courses Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3424    Accepted Submission(s): 1650 Problem Description Consider a group of N students and P courses. Each student visits zero, one or

hdu 1054 Strategic Game (二分匹配)

Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4697    Accepted Submission(s): 2125 Problem Description Bob enjoys playing computer games, especially strategic games, but somet

hdu 4907 Task schedule(二分)

# include <stdio.h> # include <string.h> # include <algorithm> using namespace std; int vis[200010]; int b[200100]; # define Max 200010 int main() { int t,T,n,m,a,i; while(~scanf("%d",&T)) { while(T--) { scanf("%d%d&qu

HDU 2289 Cup(二分可以,但是除了二分呢?)

这道题目,算数学题吗?算二分题吗?充其量算个水题吧... 首先,没有用二分,但是发现了一种新的解法来代替二分. 若果按照i从0,每次增加0.00000001来一直枚举到h的话,绝逼超时.枚举量太大了 但是可以分成两步来呀: #include<cstdio> #include<cmath> #define pai acos(-1.0) double r1,r2,h,v; double get_v(double temp) { double rr=r1+(r2-r1)*temp/h;

HDU 3622 Bomb Game(二分+2SAT)

题意:有一个游戏,有n个回合,每回合可以在指定的2个区域之一放炸弹,炸弹范围是一个圈,要求每回合的炸弹范围没有重合.得分是炸弹半径最小的值.求可以得到的最大分数. 思路:二分+2SAT. 二分炸弹范围,再根据有无重合建图,用2SAT判定. #include <cstdio> #include <cmath> #include <vector> #include <cstring> using namespace std; const int maxn =10