按照给定的规则,通过将 0 转为 1 回合来预测游戏的获胜者
给定一个仅由0和1组成的二进制字符串str ,其中0表示未占用的位置, 1表示已占用的位置。两名玩家A和B必须按照给定的规则轮流占据一个空闲位置(将 0 转换为 1):
- 玩家只能占据空闲位置
- 玩家每回合只能移动到其相邻位置
如果玩家在转牌圈不能采取行动,他就输了。假设A先走,如果双方都发挥最佳,则预测游戏的获胜者。
例子:
Input: str=”1000″
Output: A
Explanation: A makes first move and occupy position at 2nd index of the string(0 based index) then no matter which position B choose there will be only a single unoccupied position left which will be occupied by A in next turn and B can’t make further move hence A wins.
Input: str=”1001″
Output: B
方法:
- 求初始未占用位置的两个最长子串的长度(即0s的子串)。
- 如果最大子串的长度是偶数,那么无论第二大子串的长度如何, B都将是赢家。这是因为 A 将始终占据最大子串的中间位置,因此在这种情况下,它与给定子串中B的移动槽数相同。 A需要比B更多的插槽才能赢得比赛,而在这种情况下,两者的插槽数量相同,因此A会输。
- 如果最大子串的长度是奇数,那么可能有两种情况:
- 如果第二大子串的长度小于A在最大子串中的槽数(即(n/2) + 1 ,其中n是子串的大小),则A将成为赢家,因为B总是无论他最初的决定如何(在最大或第二大子串之间进行选择),都比A具有更少的槽数。
- 否则, B将成为赢家,因为B可以选择第二大子串进行初始移动,并且将比A拥有更多可用于进一步移动的插槽。
- 根据以上观察打印答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#include
using namespace std;
// Function to predict the winner
string predictWinner(string s)
{
int n = s.length();
int max1 = 0, max2 = 0;
int curr = 0;
// Loop through the string to find out
// lengths of longest two substrings of 0s
for (int i = 0; i < n; i++) {
if (s[i] == '0') {
curr++;
}
else {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1)
&& (curr > max2)) {
max2 = curr;
}
curr = 0;
}
}
if (curr > 0) {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1)
&& (curr > max2)) {
max2 = curr;
}
}
// If longest substring
// of 0s is of even length
// then B will always be the winner
if (max1 % 2 == 0) {
return "B";
}
// Slot for A's moves
// will be half the total
// number of slots plus
// one in longest substring
int left = ceil((float)max1 / 2);
// If slots for A's moves
// are more than slots in
// second largest substring
// then A will be the
// winner else B will be winner
if (left > max2) {
return "A";
}
return "B";
}
// Driver Code
int main()
{
string s = "1000";
string ans = predictWinner(s);
cout << ans;
return 0;
}
C
// C program for the above approach
#include
#include
// Function to predict the winner
char predictWinner(char s[], int n)
{
int max1 = 0, max2 = 0;
int curr = 0;
// Loop through the string to find out
// lengths of longest two substrings of 0s
for (int i = 0; i < n; i++) {
if (s[i] == '0') {
curr++;
}
else {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1) && (curr > max2)) {
max2 = curr;
}
curr = 0;
}
}
if (curr > 0) {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1) && (curr > max2)) {
max2 = curr;
}
}
// If longest substring
// of 0s is of even length
// then B will always be the winner
if (max1 % 2 == 0) {
return 'B';
}
// Slot for A's moves
// will be half the total
// number of slots plus
// one in longest substring
int left = ceil((float)max1 / 2);
// If slots for A's moves
// are more than slots in
// second largest substring
// then A will be the
// winner else B will be winner
if (left > max2) {
return 'A';
}
return 'B';
}
// Driver Code
int main()
{
char s[] = "1000";
int n = 4;
char ans = predictWinner(s, n);
printf("%c", ans);
return 0;
}
// This code is contributed by saxenaanjali239.
Java
// Java program for the above approach
import java.lang.Math;
import java.util.*;
public class GeeksForGeeks
{
// Function to predict the winner
public static String predictWinner(String s)
{
int n = s.length();
int max1 = 0, max2 = 0;
int curr = 0;
// Loop through the string to find out
// lengths of longest two substrings of 0s
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '0') {
curr++;
}
else {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1) && (curr > max2)) {
max2 = curr;
}
curr = 0;
}
}
if (curr > 0) {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1) && (curr > max2)) {
max2 = curr;
}
}
// If longest substring
// of 0s is of even length
// then B will always be the winner
if (max1 % 2 == 0) {
return "B";
}
// Slot for A's moves
// will be half the total
// number of slots plus
// one in longest substring
int left = (int)Math.ceil((float)max1 / 2);
// If slots for A's moves
// are more than slots in
// second largest substring
// then A will be the
// winner else B will be winner
if (left > max2) {
return "A";
}
return "B";
}
// Driver Code
public static void main(String args[])
{
String s = "1000";
String ans = predictWinner(s);
System.out.println(ans);
}
}
// This code is contributed by saxenaanjali239.
Python
# Python program for the above approach
import math
def predictWinner(s, n):
max1 = 0
max2 = 0
curr = 0
i = 0
# Loop through the string to find out
# lengths of longest two substrings of 0s
for i in range(n):
if s[i] == '0':
curr += 1
else:
if max1 <= curr:
max2 = max1
max1 = curr
elif (curr < max1) and (curr > max2):
max2 = curr
curr = 0
if curr > 0:
if max1 <= curr:
max2 = max1
max1 = curr
elif (curr < max1) and (curr > max2):
max2 = curr
# If longest substring
# of 0s is of even length
# then B will always be the winner
if max1 % 2 == 0:
return "B"
# Slot for A's moves
# will be half the total
# number of slots plus
# one in longest substring
left = math.ceil(max1 / 2)
# If slots for A's moves
# are more than slots in
# second largest substring
# then A will be the
# winner else B will be winner
if left > max2:
return "A"
return "B"
# Driver program to test the above function
s = "1000"
n = len(s)
ans = predictWinner(s, n)
print(ans)
# This code is contributed by saxenaanjali239.
C#
// C# program for the above approach
using System;
class GeeksForGeeks
{
// Function to predict the winner
static string predictWinner(string s)
{
int n = s.Length;
int max1 = 0, max2 = 0;
int curr = 0;
// Loop through the string to find out
// lengths of longest two substrings of 0s
for (int i = 0; i < n; i++) {
if (s[i] == '0') {
curr++;
}
else {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1) && (curr > max2)) {
max2 = curr;
}
curr = 0;
}
}
if (curr > 0) {
if (max1 <= curr) {
max2 = max1;
max1 = curr;
}
else if ((curr < max1) && (curr > max2)) {
max2 = curr;
}
}
// If longest substring
// of 0s is of even length
// then B will always be the winner
if (max1 % 2 == 0) {
return "B";
}
// Slot for A's moves
// will be half the total
// number of slots plus
// one in longest substring
int left = (int)Math.Ceiling((float)max1 / 2);
// If slots for A's moves
// are more than slots in
// second largest substring
// then A will be the
// winner else B will be winner
if (left > max2) {
return "A";
}
return "B";
}
// Driver Code
public static void Main()
{
string s = "1000";
string ans = predictWinner(s);
Console.Write(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
A
时间复杂度: O(N)
辅助空间: O(1)