📌  相关文章
📜  按照给定的规则,通过将 0 转为 1 回合来预测游戏的获胜者

📅  最后修改于: 2022-05-13 01:56:08.964000             🧑  作者: Mango

按照给定的规则,通过将 0 转为 1 回合来预测游戏的获胜者

给定一个仅由01组成的二进制字符串str ,其中0表示未占用的位置, 1表示已占用的位置。两名玩家AB必须按照给定的规则轮流占据一个空闲位置(将 0 转换为 1):

  1. 玩家只能占据空闲位置
  2. 玩家每回合只能移动到其相邻位置

如果玩家在转牌圈不能采取行动,他就输了。假设A先走,如果双方都发挥最佳,则预测游戏的获胜者。

例子:

方法:

  1. 求初始未占用位置的两个最长子串的长度(即0s的子串)。
  2. 如果最大子串的长度是偶数,那么无论第二大子串的长度如何, B都将是赢家。这是因为 A 将始终占据最大子串的中间位置,因此在这种情况下,它与给定子串中B的移动槽数相同。 A需要比B更多的插槽才能赢得比赛,而在这种情况下,两者的插槽数量相同,因此A会输。
  3. 如果最大子串的长度是奇数,那么可能有两种情况:
    • 如果第二大子串的长度小于A在最大子串中的槽数(即(n/2) + 1 ,其中n是子串的大小),则A将成为赢家,因为B总是无论他最初的决定如何(在最大或第二大子串之间进行选择),都比A具有更少的槽数。
    • 否则, B将成为赢家,因为B可以选择第二大子串进行初始移动,并且将比A拥有更多可用于进一步移动的插槽。
  4. 根据以上观察打印答案。

下面是上述方法的实现:

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)