HDU - 6261 Rikka with Mutex(二分)

本文通过解析一道竞赛编程题目,探讨了Mutex概念背后的哲学意义。题目要求找出最小人数,使得至少一人能通过一系列黑白门,模拟了互助与能量传递的过程。文章提供了详细的解题思路与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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分数就加一,遇见P就减一。如果你需要至少有一个人到达终点,并且一路上没有发生分数小于零的情况,最少需要几个人。

思路:这个题的最佳解法应该是二分人数,不过我有一个同学好像光贪心也过了(卡常数高手)。难度在于如何判断这个人数能不能到达终点。
大佬的方法简洁又明了。先派一个人出去,如果他现在所处的这个位置让分数比之前的最大值要大,那么所有人就都到那个位置。如果这一个人也到达不了终点,就是到不了。太酷了。代码很简单,就不写注释了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<math.h>
#include<vector>
#include<stack>
#include<string>
#include<set>
#include<map>
#include<numeric>
#include<stdio.h>
#include<functional>
#include<time.h>
#pragma warning(disable:6031)

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const ll mode = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double pi = 3.14159265358979323846264338327950;
template <class T> inline T min(T a, T b, T c) { return min(min(a, b), c); }
template <class T> inline T max(T a, T b, T c) { return max(max(a, b), c); }
template <class T> inline T min(T a, T b, T c, T d) { return min(min(a, b), min(c, d)); }
template <class T> inline T max(T a, T b, T c, T d) { return max(max(a, b), max(c, d)); }

char a[maxn];

bool solve(int x)
{
	int tot = 0, pre = 0, len = strlen(a);
	for(int i=0;i<len;i++)
	{
		tot += (a[i] == '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--)
	{
		getchar();
		scanf("%s", a);
		if (a[0] == 'P')
		{
			printf("-1\n");
			continue;
		}

		int left = 1, right = strlen(a);
		while (left <= right)
		{
			int mid = (left + right) / 2;
			if (solve(mid))
				right = mid - 1;
			else
				left = mid + 1;
		}
		printf("%d\n", left);
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值