HDU 6261 Rikka with Mutex (二分答案+模拟)

Rikka with Mutex

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 105    Accepted Submission(s): 37


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(1t103), 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
 
  
4VPPVPPVVVVPPPPPPPPVPPPPPPPPPPPPPPP
 

Sample Output
 
  
2314-1


/*
题意: 有string长度个门,V代表白门,P代表黑门,一个人通过一扇V总的能量增加1,通过一扇黑门
	  总的能量减少1,当能量小于0的时候不能通过黑门,问通过全部门最小需要几个人。 

思路:预处理一下,将连续的能量增减保存在数组中,然后在利用二分答案,将答案带入模拟一遍。
*/


#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+10;

char a[maxn];
int number[maxn];
int ccnt=0;

/*
	@function:将连续的区间压缩
	@param:  ccnt:区间个数 
			 vcnt:连续V的个数
			 pcnt:连续P的个数 
*/

void init(){
	int len=strlen(a),vcnt=0,pcnt=0;
	for(int i=0;i<len;i++){
		if(a[i]=='P'){
			pcnt++;
			if(vcnt>0){
				number[ccnt++]=vcnt;
			}
			vcnt=0;
		}else{
			if(pcnt>0) number[ccnt++]=0-pcnt;
			pcnt=0;
			vcnt++;
		}
	} 
	if(pcnt>0) number[ccnt++]=0-pcnt;
	else if(vcnt>0) number[ccnt++]=vcnt;
}

/*
	@function: 判断答案是否可行
	@param:	  E:总能量
			  cnt:当前步骤对整体情况是否有贡献
	@hint:    相当于一个人是探路,如果对整体有贡献,就全部人的前进,否则,此人继续前行。 
*/
bool isans(int x){
	int len=strlen(a),E=0,cnt=0;
	for(int i=0;i<ccnt;i++){
		if(number[i]>=0){
			cnt+=number[i];
			E+=number[i];
		}else if(number[i]<0){
			if(cnt>0){
				E+=(x-1)*cnt;
				cnt=0;
			}
			if(E>=-number[i]){
				cnt+=number[i];
				E+=number[i];
			}else return false;
		}
	}
	if(E<0) return false;
	else return true;
}


/*
	@function: 二分答案,去最小的可行数 
	@hint:	最多字符串长度-1的人数。(VPPP) 
*/
void solve(){
	int l=1,r=strlen(a),ans=INF;
	while(l<=r){
		int mid = (l+r)>>1;
		if(isans(mid)){
			ans=min(mid,ans);
			r=mid-1;
		}else{
			l=mid+1;
		}
	}
	printf("%d\n",ans);
}

int main(){
	int n;
	scanf("%d",&n);
	while(n--){
		ccnt=0;
		cin>>a;
		init();
		if(a[0]=='P') printf("-1\n");
		else solve();
	}
} 

猜你喜欢

转载自blog.csdn.net/rvelamen/article/details/80758659