← 返回博客列表
Microsoft

Microsoft OA Real Question Review: Maximum Score Game + Minimum Operations

2026-03-17

Microsoft OA Question 1

Question 1: Maximum Score Game

Problem Description

A game is played with the following rules:

Determine: The maximum possible score to reach the final cell

Solution Approach

Step 1: Preprocess Prime Numbers

First, find all prime numbers ending in 3 that don't exceed n. These primes are: 3, 13, 23, 43, 53, 73, 83, etc.

def get_primes_ending_with_3(max_n):
    """Get all primes <= max_n with last digit 3"""
    primes = []
    
    def is_prime(num):
        if num < 2:
            return False
        if num == 2:
            return True
        if num % 2 == 0:
            return False
        for i in range(3, int(num**0.5) + 1, 2):
            if num % i == 0:
                return False
        return True
    
    for num in range(3, max_n, 10):  # Numbers ending in 3: 3, 13, 23, 33...
        if is_prime(num):
            primes.append(num)
    
    return primes

Step 2: Dynamic Programming Solution

Use a DP array where dp[i] represents the maximum score to reach cell i.

Key Idea:

def max_score_game(cells, n):
    """
    Calculate maximum cumulative score
    
    Args:
        cells: Array of cell values
        n: Total number of cells
    
    Returns:
        Maximum score to reach the final cell
    """
    # Preprocess primes
    primes = get_primes_ending_with_3(n)
    
    # DP initialization
    dp = [-float('inf')] * n
    dp[0] = cells[0]  # Starting cell value is 0
    
    # State transition
    for i in range(n):
        if dp[i] == -float('inf'):
            continue  # Skip unreachable positions
        
        # Try moving 1 step
        if i + 1 < n:
            dp[i + 1] = max(dp[i + 1], dp[i] + cells[i + 1])
        
        # Try moving p steps (p is a prime ending in 3)
        for p in primes:
            if i + p < n:
                dp[i + p] = max(dp[i + p], dp[i] + cells[i + p])
            else:
                break  # Subsequent primes are larger, no need to continue
    
    return dp[n - 1]

Step 3: Example Walkthrough

Given: cells = [0, -10, -20, -30, 50], n = 5

Final Answer: 40

Time Complexity Analysis

Common Pitfalls

Pitfall 1: Forgetting to initialize unreachable positions to negative infinity ✅ Solution: Clearly distinguish between reachable and unreachable states

Pitfall 2: Incomplete prime preprocessing, missing some primes ✅ Solution: Use sieve method or verify each number to ensure all primes ending in 3 are found

Pitfall 3: Not handling negative cell values correctly ✅ Solution: Initialize DP to negative infinity and handle all values properly


Question 2: Minimum Operations

Microsoft OA Question 2

Problem Description

Given a positive integer n, in each operation you can either:

Determine: The minimum number of operations required to reduce n to 0

Solution Approach

Core Observation: Binary Greedy

The key to this problem is observing the binary representation of n and utilizing the properties of binary carries.

Key Rules:

Detailed Algorithm

def min_operations(n):
    """
    Calculate minimum operations to reduce n to 0
    
    Args:
        n: Positive integer
    
    Returns:
        Minimum number of operations
    """
    operations = 0
    
    while n > 0:
        # Observe the last two binary digits of n
        last_two_bits = n & 3  # Get last two bits: n % 4
        
        if last_two_bits == 0:
            # 00: Shift right directly
            n >>= 1
        elif last_two_bits == 1:
            # 01: Subtract 1 (becomes 00), then shift right
            n -= 1
            operations += 1
        elif last_two_bits == 2:
            # 10: Shift right directly
            n >>= 1
        else:  # last_two_bits == 3
            # 11: Add 1 (carry over to become 100), then shift right
            n += 1
            operations += 1
        
        operations += 1  # Count the shift operation
    
    return operations

Algorithm Explanation

Why does this work?

Observe the last two binary digits:

  1. 00: Last bit is 0, shift right directly
  2. 01: Last bit is 1, subtract 1 to make it 00, then shift right
  3. 10: Last bit is 0, shift right directly
  4. 11: Both last two bits are 1, adding 1 causes a carry (becomes 100), then shift right

Benefits of this approach:

Example Walkthrough

For n = 5:

n = 5 = 101₂

Step 1: Last two bits are 01
  - Subtract 1: 5 - 1 = 4 = 100₂ (operation 1)
  - Shift right: 4 >> 1 = 2 = 10₂ (operation 2)

Step 2: Last two bits are 10
  - Shift right: 2 >> 1 = 1 = 1₂ (operation 3)

Step 3: Last two bits are 01
  - Subtract 1: 1 - 1 = 0 (operation 4)
  - Shift right: 0 >> 1 = 0 (operation 5)

Total operations: 5

Verification: 5 → 4 → 2 → 1 → 0
            (sub 1) (÷2) (÷2) (sub 1)

Wait, let me reconsider. The problem asks for operations where each operation is adding or subtracting a power of 2.

Reconsidering the Problem

Actually, we need to reconsider: each operation is adding or subtracting a power of 2, and we want the minimum number of such operations.

This is equivalent to representing n using the minimum number of powers of 2.

For example:

So the optimal is 2 operations.

Improved Algorithm

def min_operations_v2(n):
    """
    Calculate minimum operations to reduce n to 0 (improved version)
    
    Uses the count of 1s in binary representation as the base
    """
    operations = 0
    
    while n > 0:
        last_two_bits = n & 3
        
        if last_two_bits == 0:
            # 00: Shift right
            n >>= 1
        elif last_two_bits == 1:
            # 01: Subtract 1
            n -= 1
            operations += 1
        elif last_two_bits == 2:
            # 10: Shift right
            n >>= 1
        else:  # last_two_bits == 3
            # 11: Add 1 (carry)
            n += 1
            operations += 1
    
    return operations

For n = 5:

5 = 101₂
Last two bits are 01 → Subtract 1 → 4 = 100₂ (operation 1)
Last two bits are 00 → Shift right → 2 = 10₂
Last two bits are 10 → Shift right → 1 = 1₂
Last two bits are 01 → Subtract 1 → 0 (operation 2)

Total operations: 2 ✓

Time Complexity Analysis

Common Pitfalls

Pitfall 1: Confusing "operations" with "shift operations" ✅ Solution: Only additions and subtractions count as operations; shifts are free

Pitfall 2: Not utilizing the carry property ✅ Solution: When the last two bits are 11, adding 1 creates a carry that can merge multiple 1s

Pitfall 3: Incorrect greedy strategy ✅ Solution: Observe the last two bits and follow the rules


Interview Strategy

Time Management

Question 1 (Maximum Score Game):

Question 2 (Minimum Operations):

On-Site Tips

  1. Question 1:

    • Confirm the definition of primes (ending in 3)
    • Clarify boundary conditions (cannot exceed n-1)
    • Start with simple examples to derive the solution
  2. Question 2:

    • Use several examples to find patterns
    • Observe binary representations
    • Explain why adding or subtracting 1 is optimal

Common Questions

Q: Will the algorithm work if n is very large (close to 2^60)?

A: Yes. Question 2 has O(log n) time complexity, so even n = 2^60 requires only about 60 iterations. Question 1 requires preprocessing primes, but the density of primes ending in 3 is sufficient and won't be a bottleneck.

Q: What if all cell values in Question 1 are negative?

A: You still need to reach the final cell, so choose the path with the smallest total loss. The DP algorithm handles this automatically.

Q: Is there an alternative approach to Question 2?

A: Yes. Question 2 is essentially finding the minimum number of powers of 2 to represent n. You could also use BFS or memoized search, but binary greedy is optimal.


Complete Code Implementation

def get_primes_ending_with_3(max_n):
    """Get all primes <= max_n with last digit 3"""
    primes = []
    
    def is_prime(num):
        if num < 2:
            return False
        if num == 2:
            return True
        if num % 2 == 0:
            return False
        for i in range(3, int(num**0.5) + 1, 2):
            if num % i == 0:
                return False
        return True
    
    for num in range(3, max_n, 10):
        if is_prime(num):
            primes.append(num)
    
    return primes


def max_score_game(cells):
    """Calculate maximum cumulative score"""
    n = len(cells)
    primes = get_primes_ending_with_3(n)
    
    dp = [-float('inf')] * n
    dp[0] = cells[0]
    
    for i in range(n):
        if dp[i] == -float('inf'):
            continue
        
        # Move 1 step
        if i + 1 < n:
            dp[i + 1] = max(dp[i + 1], dp[i] + cells[i + 1])
        
        # Move p steps
        for p in primes:
            if i + p < n:
                dp[i + p] = max(dp[i + p], dp[i] + cells[i + p])
            else:
                break
    
    return dp[n - 1]


def min_operations(n):
    """Calculate minimum operations to reduce n to 0"""
    operations = 0
    
    while n > 0:
        last_two_bits = n & 3
        
        if last_two_bits == 0:
            n >>= 1
        elif last_two_bits == 1:
            n -= 1
            operations += 1
        elif last_two_bits == 2:
            n >>= 1
        else:  # last_two_bits == 3
            n += 1
            operations += 1
    
    return operations


# Test cases
if __name__ == "__main__":
    # Test Question 1
    cells = [0, -10, -20, -30, 50]
    print(f"Maximum score: {max_score_game(cells)}")  # Output: 40
    
    # Test Question 2
    print(f"Minimum operations: {min_operations(5)}")  # Output: 2

🚀 Need Interview Assistance?

oavoservice provides professional OA/VO assistance services to help you quickly pass technical interviews at major tech companies like Microsoft, Amazon, and more.

👉 Contact WeChat: Coding0201