#2020.01.14训练题解#二分入门(E题)

题源HDU-6261

HDU-6261-Rikka with Mutex

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

题意

  • 输入一个字符串string,字符串的长度就是门的个数,V代表白门,P代表黑门
  • 一个人通过一扇V时,总的能量增加1,通过一扇黑门,总的能量减少1
  • 当能量小于0的时候不能通过黑门
  • 初始能量每个人都是0,那么总能量池也是0
  • 问至少一个人通过全部门,最小需要几个人

题解

  • 所有人共用能量,无论谁通过了哪扇门,总的能量池都会变化
  • 比如10个人一起通过V,那么能量池里的能量就 +10
  • 最后的目的就是,总的能量够至少一个人自己走到终点

  • 如果有一排门VVVPPPP
  • 可以先让一个人去试探——冲锋陷阵.jpg
  • 如果他往前走到某个位置,总能量上涨
  • 那么其余的人都可以跟上来到这个位置
  • 因为一个人涨,大家一起过来,就会涨得更多
  • 一个人,大家一起过来,只会跌得更多
  • 所以要保证实现最大的能量,然后用这些能量护体保冲锋军平安

  • 如果第一扇门就是P,无论怎么走,谁走,能量池都将变成负数
  • 所以只有当第一扇门不是P的时候才有可能实现计划(接下来的阐述假设第一扇门不是P)
  • 最糟糕的情况就是第一扇门是V后面全部是P
  • 那么,包括第一扇门一共len扇门最多只要安排len-1个人就够啦
  • 以上的最多,是指最少中的最多要求最少人数,最糟糕的情况下发生的就是最多的情况
  • 虽然一共len扇门,安排len,len+1,len+10086…个人肯定都能过,但不做讨论
  • 所以二分的对象是人数!!!每次只要验证这个人数能否满足题意即可啦

  • 【mid变量】 找人数
  • 【total变量】 能量池
  • 【solve函数】 判断是否可以解决题目的问题
  • 如果人数满足,那么别忘了试试更小的数,毕竟是找最少要多少人嘛(o゚▽゚)o

涉及知识点

  • 二分 算法(此题属于整数二分)
  • 对于二分的算法-详见链接博客介绍二分

AC代码

#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
string put;
int check(int mid)
{
	int len=put.length(),total=0,before=total;
	for(int i=0;i<len;i++)
	{
		if(put[i]=='P') total--;
		else total++;
		if(total<0) return 0;
		else
		{
			if(total<=before) continue;
			else
			{
				total+=mid-1;
				before=total;
			}
		}
	}
	return 1;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>put;
		if(put[0]=='P') printf("-1\n");
		else//二分所需要的人数,1-put.length() 
		{
			int left=1,right=put.length(),mid;
			while(left<=right)
			{//left==right的时候还要判断是否可以check,如果不可以,还要放大一位 
				mid=(left+right)>>1; 
				//用>>1位移代替/2时间复杂度更小
				if(check(mid)) right=mid-1;
				else left=mid+1;
			}
			cout<<left<<endl;
		}
	}
	return 0;
}
发布了20 篇原创文章 · 获赞 0 · 访问量 401

猜你喜欢

转载自blog.csdn.net/qq_46184427/article/details/104073801