zoukankan      html  css  js  c++  java
  • 「HDU3640」I,Zombie

    题意:原题在这
     
    原创翻译:
    有一份只有一行的植物大战僵尸地图:
                    50hp的普通僵尸。
                    两种植物:豌豆射手(10hp)和土豆雷(一次性)。
     
     
    每秒的操作步骤如下:
              1.在最右侧的草皮中逐个放置0<=num的僵尸 (在最右边草皮的右边,即地图之外)
              2.判断每一个幸存的僵尸,是否站在一个豌豆射手身上:
                if true,攻击这个豌豆射手,豌豆射手hp -1.豌豆射手的hp在那一刻可能是负值,但它仍然活着!
                if false,向左移动一格。
              3.如果地图上还有僵尸,每一个幸存的豌豆射手都会向最早放置的僵尸射击(僵尸每被锤一下hp -1,僵尸的hp在那一刻可能是负值,但它仍然活着!)
              4.如果在土豆雷的草皮中有僵尸,那么土豆雷爆炸,这个草皮中所有僵尸的hp变为0。
              5.非正hp的植物和僵尸消失(直到现在它们已经死亡)

     

    请根据所给的地图,求僵尸胜利的最小个数.

     

    方法及思路:转自:全网唯一一篇题解
    模拟,主要有三个问题要维护,一是植物的长度,二是最右边的植物种类,三是僵尸距离最近的植物的步数。
     
    如果僵尸碰到了地雷,那么下一回合可以认为僵尸的最左位置为炸弹的左边。(僵尸左移)
     
    如果碰到的不是地雷,则不停向左统计植物个数,直到遇到第一个炸弹
     
    然后二分可以吃掉这些植物的最少僵尸个数,二分时要根据条件进行模拟。
     
     
    其余详见代码注释↓
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 int T;
      8 int P,M,len,Zombie,Step;
      9 char plant[150];
     10 
     11 void init(char p[])
     12 {
     13     Zombie=P=M=0;
     14     len=strlen(p)-1;
     15     for(int i=0;i<=len;i++)
     16     {
     17         if(p[i]=='P')
     18             P++;
     19         else
     20             M++;
     21     }
     22 }
     23 
     24 int solve(int sum,int plnt,int zom)//植物总数,豌豆个数,僵尸个数
     25 {
     26     int flag=Step;//距离最近植物的步数
     27     int plnt_life=10,zom_life=50;//初始生命值
     28     while(plnt>0 && zom>0)
     29     {
     30         if(flag>0)//还没到最近的植物
     31         {
     32             flag--;//走一步
     33             zom_life-=sum;//这个僵尸会被所有植物锤
     34         }
     35         else//到了最近的植物
     36         {
     37             plnt_life-=zom;//这个豌豆会被所有僵尸锤
     38             zom_life-=sum;//这个僵尸会被所有植物锤
     39         }
     40         if(plnt_life<=0)//死了一个射手
     41         {
     42             plnt_life=10;
     43             sum--; plnt--;
     44             flag=1;
     45         }
     46         if(zom_life<=0)//死了一个僵尸
     47         {
     48             zom_life=50;
     49             zom--;
     50         }
     51     }
     52     if(plnt<=0 && zom>0)//僵尸赢辣
     53         return 1;
     54     if(plnt<=0 && zom<=0)//都死光了
     55         return 0;
     56     if(plnt>0)//植物还活着
     57         return -1;
     58 }
     59 
     60 int main()
     61 {
     62     cin>>T;
     63     for(int cas=1;cas<=T;cas++)
     64     {
     65         cin>>plant;
     66         init(plant);
     67         if(plant[len]=='M')//有地雷
     68         {
     69             len--;//先牺牲一个僵尸同归于尽
     70             Zombie++;//僵尸前进一步
     71             Step=2;
     72         }
     73         else
     74             Step=1;
     75         while(len>=0)//只要还没到brain处
     76         {
     77             if(plant[len]=='M')//前面是地雷
     78             {
     79                 if(Step>1)//还没到地雷
     80                 {
     81                     Step--;//走一步
     82                     if(P>=50) Zombie++;//并且打得过,那么干死一个僵尸
     83                     continue;
     84                 }
     85                 else
     86                     Zombie++;//死一个僵尸
     87                 M--; len--;//消耗一颗地雷
     88                 Step=2;
     89             }
     90 
     91             else//前面是豌豆射手
     92             {
     93                 //从后往前统计豌豆个数
     94                 int pNum=0;
     95                 for(int i=len;i>=0;i--)
     96                 {
     97                     if(plant[i]=='M')
     98                         break;
     99                     else
    100                         pNum++;
    101                 }
    102                 //二分最少僵尸个数
    103                 int left=1,right=300,mid;
    104                 while(left<right)//直至二分出答案
    105                 {
    106                     mid=(left+right)>>1;
    107                     if(solve(P,pNum,mid)>0)//如果这种情况下僵尸赢
    108                         right=mid;
    109                     else
    110                         left=mid+1;
    111                 }
    112                 Zombie+=left;//加上二分出的答案
    113                 P-=pNum;
    114                 len-=pNum+1;
    115                 Step=2;
    116             }
    117         }
    118         if(plant[0]=='M')//判断一开始是地雷
    119             Zombie++;
    120         printf("Case %d: %d
    ",cas,Zombie);
    121     }
    122     return 0;
    123 }
  • 相关阅读:
    Python Twelfth Day
    Python Tenth Day
    Python Ninth Day
    Python Eighth Day
    Python Seventh Day
    Python Sixth Day
    Python Fifth Day
    Python Fourth Day
    Python Third Day
    金融量化分析-python量化分析系列之---使用python的tushare包获取股票历史数据和实时分笔数据
  • 原文地址:https://www.cnblogs.com/LocaEtric/p/9150894.html
Copyright © 2011-2022 走看看