HDU 3640【非常复杂模拟题+二分】

题目:I, zombie

题意:

植物大战僵尸的模拟题,地图只有一行,两种植物,一种会射弹,一种是炸弹,求僵尸胜利的最小个数。

解题思路:

第一感觉是没感觉,然后觉得好繁杂,各种情况。经过长久琢磨后,思路慢慢清晰,然后AC。觉得还是挺好的一道模拟题。

模拟时主要有三个问题要维护,一是植物的长度,二是最右边的植物种类,三是僵尸最左的位置。如果僵尸碰到的是炸弹,那么下一回合可以认为僵尸的最左位置为炸弹的左边。如果碰到的不是炸弹,则不停向左统计植物个数,直到遇到第一个炸弹,然后二分可以吃掉这些植物的最少僵尸个数,二分时要根具条件进行模拟。

View Code
  1 #include <iostream>
2 #include <cstdio>
3 #include <string>
4 #include <cstring>
5 #include <algorithm>
6 #include <vector>
7 #include <map>
8
9 using namespace std;
10
11 const int MAX = 100 + 10;
12 char Plant[MAX];
13 int P, M;
14 int Flag;
15 int E;
16 int MozNum;
17 void init(char plant[])
18 {
19 MozNum = 0;
20 E = strlen(plant) - 1;
21 P = M = 0;
22 for(int i = 0; i <= E; ++i)
23 {
24 if(plant[i] == 'P')
25 ++P;
26 else
27 ++M;
28 }
29 }
30
31 int run(int apNum, int ppNum, int mozNum)
32 {
33 int flag = Flag;
34 int pLife = 10, mozLife = 50;
35 while(ppNum > 0 && mozNum > 0)
36 {
37 if(flag > 0)
38 {
39 --flag;
40 mozLife -= apNum;
41 }
42 else
43 {
44 pLife -= mozNum;
45 mozLife -= apNum;
46 }
47 if(pLife <= 0)
48 {
49 pLife = 10;
50 apNum--;
51 ppNum--;
52 flag = 1;
53 }
54 if(mozLife <= 0)
55 {
56 mozLife = 50;
57 mozNum--;
58 }
59 }
60 if(ppNum <= 0 && mozNum > 0)
61 return 1;
62 if(ppNum <= 0 && mozNum <= 0)
63 return 0;
64 if(ppNum > 0)
65 return -1;
66 }
67 int main()
68 {
69 freopen("in.txt", "r", stdin);
70 int T;
71 scanf("%d", &T);
72 for(int t = 1; t <= T; ++t)
73 {
74 scanf("%s", Plant);
75 init(Plant);
76 if(Plant[E] == 'M')
77 {
78 E--;
79 MozNum++;
80 Flag = 2;
81 }
82 else
83 Flag = 1;
84 while(E >= 0)
85 {
86 if(Plant[E] == 'M')
87 {
88 if(Flag > 1)
89 {
90 --Flag;
91 if(P >= 50)
92 ++MozNum;
93 continue;
94 }
95 else
96 MozNum++;
97 M--;
98 E--;
99 Flag = 2;
100 }
101 else
102 {
103 int pNum = 0;
104 for(int i = E; i >= 0; --i)
105 {
106 if(Plant[i] == 'M')
107 break;
108 else
109 pNum++;
110 }
111 int left = 1, right = 2 * MAX, mid;
112 while(left < right)
113 {
114 mid = (left + right) >> 1;
115 if(run(P, pNum, mid) > 0)
116 right = mid;
117 else
118 left = mid + 1;
119 }
120 MozNum += left;
121 P -= pNum;
122 E -= pNum + 1;
123 Flag = 2;
124 }
125 }
126 if(Plant[0] == 'M')
127 ++MozNum;
128 printf("Case %d: %d\n", t, MozNum);
129 }
130 return 0;
131 }



posted on 2011-10-05 22:35  Kenfly  阅读(824)  评论(0编辑  收藏  举报