"Algorithm Competition·Quickly 300 Questions" One question per day: "Getting stones game"

" Algorithm Competition: 300 Quick Questions " will be published in 2024 and is an auxiliary exercise book for "Algorithm Competition" .
All questions are placed in the self-built OJ New Online Judge .
Codes are given in three languages: C/C++, Java, and Python. The topics are mainly mid- to low-level topics and are suitable for entry-level and advanced students.


" Pebble Game ", link: http://oj.ecustacm.cn/problem.php?id=1119

Question description

[Problem description] There are two piles of stones, and two people take turns to pick them up. Each time you take it, you can only take it from the larger pile of stones, and the number taken must be an integral multiple of the number of the smaller pile of stones. Whoever can empty the pile of stones in the end wins. Given the initial number of stones, if both people adopt the optimal strategy, ask whether the first player can win.
[Input format] The input contains most data. Each set of data contains one row, containing two positive integers a and b, representing the initial number of stones. a, b≤109. The input ends with two zeros.
[Output format] If the first player wins, output "win", otherwise output "lose".
【Input sample】

34 12
15 24
0 0

【Output sample】

win
lose

answer

   Let a≥b. The one who can take the empty stone at present wins, then the current situation is required to be a=kb, that is, a is an integer multiple of b, and the one who takes the empty stone wins.
   The first example, "34, 12", is:
      A: 34-24, 12 -> 10, 12,
      B: 10, 12-10 -> 10, 2, B has only this
      method : A: 10-10 , 2 -> 0, 2, Jia Sheng
   readers can simulate the second example by themselves.
   The game situations under different situations are discussed below. Assume a≥b at the beginning.
   (1) Situation 1: a = b. The first mover wins because he can empty the pile.
   (2) Position 2: b < a < 2b. This position is disadvantageous for the first player, because he has no choice but to take b from the pile of a, leaving ab. The new two piles are a' = b, b' = ab. Note that there is a'≠b', the game is not over, there is still a chance to go first. If there is still b' <a' < 2b' in the next step, the unfavorable situation will be transferred to the opponent. If a' ≥ 2b', see discussion of situation (3).
   (3) Position 3: a≥2b.
   If a is exactly k times of b, a = kb, then the first mover directly shorts a=kb, and the first mover wins.
   If a is not an integral multiple of b, the first mover can take a certain multiple of b and switch to position 2, putting the opponent at a disadvantage and still maintaining an advantage when it is his turn in subsequent positions.
   For example, a=13, b=5, A takes the lead, so take:
      A: 13-5, 5 -> 8, 5, the next step (8, 5) changes to position 2, putting B in a disadvantageous position
      B: 8- 5, 5 -> 3, 5, B has only this choice
      A: 3, 5-3 -> 3,
      B: 3-2, 2 -> 1, 2, B has only this choice
      A: 1, 2-2 -> 1, 0, A wins.
   If A does not take the right first step, it will lead to failure:
      A: 13-10, 5 -> 3, 5
      B: 3, 5-3 -> 3, 2, B has only one choice
      A: 3-2, 2 -> 1, 2, A has only one choice
      B : 1, 2-2 -> 1, 0, B wins.
   In other words, A has two choices, one is to lose, the other is to win. He will definitely choose the winning one.
   To summarize the above discussion, the conditions for winning first are that you are currently in positions 1 and 3.
[Key points] Situation analysis.

C++ code

   Convert the game situation in dfs() and return the result. What is the complexity of dfs()? Line 6 executes dfs(ab, b) when b < a < 2b. Each time ab is reduced by at least half, so the complexity is O (loga) O(loga)O ( l o g a ) , thisa = 1 0 9 a=10^9a=109 o'clock,loga = 30 loga = 30l o g a=30

#include<bits/stdc++.h>
using namespace std;
bool dfs(int a, int b){
    
    
    if(a < b)  swap(a, b);      //保证多的石子在前
    if(a >= 2*b || a==b) return true;  //当前处于局面1、局面3,获胜
    return !dfs(a-b, b);      //局面2,对方只能取a-b
}
int main(){
    
    
    int a, b;
    while(cin>>a>>b && (a+b)) {
    
    
        if(dfs(a, b)) cout<<"win" <<endl;
        else          cout<<"lose"<<endl;
    }
    return 0;
}

Java code

import java.util.Scanner;
public class Main {
    
    
    public static boolean dfs(int a, int b) {
    
    
        if (a < b) {
    
    
            int temp = a;
            a = b;
            b = temp;
        }
        if (a >= 2 * b || a==b)  return true;
        return !dfs(a - b, b);
    }
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
    
    
            int a = sc.nextInt();
            int b = sc.nextInt();
            if (a == 0 && b == 0)  break;            
            if (dfs(a, b)) System.out.println("win");
            else           System.out.println("lose");            
        }
        sc.close();
    }
}

Python code

def dfs(a, b):
    if a < b:  a, b = b, a           #交换
    if a >= 2 * b or a==b: return True
    return not dfs(a - b, b) 
while True:
    a, b = map(int, input().split())
    if a == 0 and b == 0:  break
    if dfs(a, b):  print("win")
    else:          print("lose")

Guess you like

Origin blog.csdn.net/weixin_43914593/article/details/132636321