Rikka with Mutex
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 132 Accepted Submission(s): 28
Problem Description
Sometimes, technical terms implicate some life philosophy. Mutex is one of them. On your way to dream, you may be locked by some difficulties, and you need someone to stop his step, and help you get through them.
To help you know better about the life philosophy inside mutex, Rikka comes up with a simple task. Maybe some of you know little about mutex, so she uses another scene to replace it.
There are n gates in a row, several people in the left side of the gates and all of them want to go to the right side. There are two kinds of gates: black and white. These people share energy, which is represented by a non-negative number E. Initially, E=0.
If one person walks through a white gate, he will gain one point of energy, i.e., E will be added by 1. And if one person walks through a black gate, he will lose one point of energy, i.e., E will be subtracted by 1. Since E must be a non-negative integer, if E=0, no one can walk through a black gate until someone walks through a white gate. You can assume there won't be two people moving at the same time and all the people are selfless.
We use P to represent a black gate, V to represent a white gate and use a PV string to represent the row. Initially, all the people are at the beginning of the string, and all of them want to go through the whole string. But unfortunately, sometimes it may be impossible. So, they want to send at least one person to the right side.
Your task is to find out the minimal number of people which this group needs to achieve this goal.
For example, if the row is VPP, they need at least two people: The first person walk through the first white gate and the second person can use this point of energy to go through the whole string.
Input
The first line contains a single numner t(1≤t≤103), the number of the testcases.
For each testcase, the first line contains a PV string s(1≤|s|≤105) describing the gates.
The input guarantees that there are at most 30 testcases with |S|>1000.
Output
For each testcase, output a single integer, the answer. And if it is impossible, output −1.
Sample Input
4 VPP VPPVVVVPPPPPPPP VPPPPPPPPPPPPPP P
Sample Output
2 3 14 -1
题意:给一个字符串,一个人从第一个出发到最后一个,其中遇到V生命值加上1,遇到P生命值减去1,任何时候生命都不允许是负数,问初始至少要安排几个人,才能使得至少有一个人能够到达终点(所有人共用生命值)。
思路:冬令营的题目,首先考虑二分答案,怎么选择验证的策略呢?假如字符串是VVVVVPPPVVPP,一开始肯定是所有人走到第五个V处获得最多的生命值,记为tot,然后此时判断生命值足不足够派一个人去到终点,如果还不足够,就派一个人自己往前走直到生命值比tot大就停止,然后剩下的人全部跟上来。此策略可以保证生命值最多,因为如果派一个人往前走tot不断减少,再派其他人跟上来也许会使情况更糟糕,如果一直没遇到比tot大的点,说明走不到终点。
这题当时没做出来,要反思一下二分答案的精髓,其实二分一个答案mid,check的时候只要考虑 如果答案是mid,这mid个全部用完它,按照某个策略一定能完成或者如果不是这样就一定完不成。而不是check的时候还去考虑“标准”的完成方法。
# include <iostream>
# include <cstring>
# include <cstdio>
using namespace std;
char s[100003];
int len;
bool ok(int x)
{
int tot = 0, pre = 0, one = 0;
while(one < len)
{
++one;
tot += (s[one]=='P'?-1:1);
if(tot < 0) return false;
else if(tot > pre) tot = tot+(tot-pre)*(x-1), pre=tot;
}
return true;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s+1);
len = strlen(s+1);
if(s[1] == 'P') puts("-1");
else
{
int l=1, r=len;
while(l <= r)
{
int mid = l + r >> 1;
if(ok(mid)) r = mid - 1;
else l = mid + 1;
}
printf("%d\n",l);
}
}
return 0;
}