MAP - TREEMAP - DICT

This session covers map-based data structures including hash maps, tree maps, and dictionary operations for efficient key-value storage and retrieval.

Problems

Megacity

Problem Information

  • Source: Codeforces
  • Difficulty: Secret
  • Time Limit: 2000ms
  • Memory Limit: 256MB

Problem Statement

The city of Berland wants to become a megacity (population >= 1,000,000). There are n locations around the city, each at coordinates (x, y) with k people. The city can expand its borders to a circle of radius r centered at origin (0,0). Find the minimum radius r such that the city population reaches 1,000,000.

Input Format

  • First line: n (number of locations) and s (current city population)
  • Next n lines: x, y, k (coordinates and population of each location)

Output Format

  • Minimum radius r (to 7 decimal places) to reach population 1,000,000
  • Print -1 if impossible

Example

Input:
4 999998
1 1 1
2 2 1
3 3 1
4 4 1

Output:
2.8284271

The city needs 2 more people to reach 1,000,000. The closest locations are at (1,1) and (2,2) with distances ~1.41 and ~2.83. After including both, the minimum radius is sqrt(8) = 2.8284271.

Solution

Approach

Calculate distance from origin to each location. Sort locations by distance. Greedily add locations (closest first) until population >= 1,000,000. Uses dictionary/sorting for efficient location management.

Python Solution
import math


def solution():
  n, s = map(int, input().split())
  # Use tuples (distance, population) instead of a class
  locations = []
  for _ in range(n):
    x, y, k = map(int, input().split())
    locations.append((math.hypot(x, y), k))

  locations.sort()

  min_r = 0
  for r, k in locations:
    if s >= 1000000:
      print(round(min_r, 7))
      return
    s += k
    min_r = r

  print(round(min_r, 7) if s >= 1000000 else -1)


solution()
Complexity Analysis
  • Time Complexity: O(n log n) for sorting
  • Space Complexity: O(n)

Powers of Two

Problem Information

  • Source: Codeforces
  • Difficulty: Secret
  • Time Limit: 3000ms
  • Memory Limit: 256MB

Problem Statement

Given an array of n integers, count the number of pairs (i, j) where i < j such that a[i] + a[j] is a power of 2.

Input Format

  • First line: n (number of elements)
  • Second line: n space-separated integers a[1], a[2], …, a[n]

Output Format

  • Single integer: number of pairs whose sum is a power of 2

Example

Input:
4
7 1 5 3

Output:
3

Valid pairs: (7,1)=8=2^3, (1,7) already counted, (5,3)=8=2^3, (1,3)=4=2^2. The pairs (0,1), (0,3), (2,3) give sums 8, 4, 8 respectively, totaling 3 pairs.

Solution

Approach

Use a dictionary (hash map) to store frequency of each number seen so far. For each element, check all powers of 2 (up to 2^60) and count pairs. For each power p, if (p - a[i]) exists in dictionary, add its count. Time complexity: O(n * 60) using hash map for O(1) lookups.

Python Solution
from collections import defaultdict


def solution():
  n = int(input())
  a = list(map(int, input().split()))

  pow2 = [1 << i for i in range(61)]  # Bit shift is more Pythonic for powers of 2

  total = 0
  count = defaultdict(int)
  for num in a:
    total += sum(count[p - num] for p in pow2)
    count[num] += 1

  print(total)


solution()
Complexity Analysis
  • Time Complexity: O(n * 60) = O(n)
  • Space Complexity: O(n)

Penguins

Problem Information

  • Source: ACM TIMUS
  • Difficulty: Secret
  • Time Limit: 1000ms
  • Memory Limit: 64MB

Problem Statement

A group of penguins have names. Find the most frequently occurring name among all the penguins. If there’s a tie, return the name that appeared first with the maximum count.

Input Format

  • First line: n (number of penguins)
  • Next n lines: name of each penguin

Output Format

  • The most common penguin name

Example

Input:
5
Tux
Happy
Tux
Happy
Tux

Output:
Tux

“Tux” appears 3 times, “Happy” appears 2 times. The most frequent name is “Tux”.

Solution

Approach

Use a dictionary to count occurrences of each name. Track the most frequent name while iterating. Simple hash map frequency counting problem.

Python Solution
from collections import defaultdict


def solution():
  penguins = defaultdict(int)
  n_penguins = int(input())
  most_count = 0
  most_common = ''

  for _ in range(n_penguins):
    penguin = input().strip()
    penguins[penguin] += 1
    if penguins[penguin] > most_count:
      most_count = penguins[penguin]
      most_common = penguin

  print(most_common)


solution()
Complexity Analysis
  • Time Complexity: O(n)
  • Space Complexity: O(n)

Isenbaev’s Number

Problem Information

  • Source: ACM TIMUS
  • Difficulty: Secret
  • Time Limit: 1000ms
  • Memory Limit: 64MB

Problem Statement

In competitive programming, “Isenbaev’s Number” represents the shortest chain of teammates connecting a person to Isenbaev (similar to Erdos number). Given a list of 3-person teams, calculate each person’s Isenbaev number. Isenbaev himself has number 0, his teammates have number 1, etc.

Input Format

  • First line: n (number of teams)
  • Next n lines: three space-separated names (team members)

Output Format

  • For each unique name (in alphabetical order), print: “name number” or “name undefined” if not connected to Isenbaev

Example

Input:
3
Isenbaev Petrov Sidorov
Sidorov Ivanov Kozlov
Kozlov Fedorov Romanov

Output:
Fedorov 3
Isenbaev 0
Ivanov 2
Kozlov 2
Petrov 1
Romanov 3
Sidorov 1

Isenbaev has number 0. Petrov and Sidorov are teammates with Isenbaev, so they have number 1. Ivanov and Kozlov teamed with Sidorov, getting number 2. And so on.

Solution

Approach

Use dictionary to store each person’s proximity to Isenbaev. For each team, propagate the minimum proximity value. Sort and output results alphabetically.

Python Solution
from collections import defaultdict

INF = int(1e9)


def solution():
  players = defaultdict(lambda: INF)
  players['Isenbaev'] = 0
  n_teams = int(input())

  for _ in range(n_teams):
    team = input().split()
    # Find minimum proximity in this team
    min_proximity = min(players[p] for p in team)

    if min_proximity < INF:
      for player in team:
        if players[player] > min_proximity:
          players[player] = min_proximity + 1

  for name in sorted(players.keys()):
    proximity = str(players[name]) if players[name] != INF else 'undefined'
    print(f"{name} {proximity}")


solution()
Complexity Analysis
  • Time Complexity: O(n * k + m log m) where k is team size, m is unique players
  • Space Complexity: O(m)

Test Task

Problem Information

  • Source: ACM TIMUS
  • Difficulty: Secret
  • Time Limit: 1000ms
  • Memory Limit: 64MB

Problem Statement

Implement a simple user authentication system with three operations:

  • register login password: Register a new user
  • login login password: Log in an existing user
  • logout login: Log out a logged-in user

Each operation outputs success/fail with appropriate message.

Input Format

  • First line: n (number of operations)
  • Next n lines: operation with arguments

Output Format

  • For each operation, print the result message:
    • register: “success: new user added” or “fail: user already exists”
    • login: “success: user logged in” or appropriate fail message
    • logout: “success: user logged out” or appropriate fail message

Example

Input:
6
register alice password123
login alice password123
login alice password123
logout alice
logout alice
login bob wrongpass

Output:
success: new user added
success: user logged in
fail: already logged in
success: user logged out
fail: already logged out
fail: no such user

Solution

Approach

Use dictionary to store user credentials and login state. Each user maps to [password, status] where status is ‘in’ or ‘out’.

Python Solution
def solution():
  n = int(input())
  users = {}  # {login: [password, logged_in]}

  for _ in range(n):
    parts = input().split()
    op, login = parts[0], parts[1]

    if op == 'register':
      if login in users:
        print('fail: user already exists')
      else:
        users[login] = [parts[2], False]
        print('success: new user added')

    elif op == 'login':
      if login not in users:
        print('fail: no such user')
      elif users[login][0] != parts[2]:
        print('fail: incorrect password')
      elif users[login][1]:
        print('fail: already logged in')
      else:
        users[login][1] = True
        print('success: user logged in')

    elif op == 'logout':
      if login not in users:
        print('fail: no such user')
      elif not users[login][1]:
        print('fail: already logged out')
      else:
        users[login][1] = False
        print('success: user logged out')


solution()
Complexity Analysis
  • Time Complexity: O(n)
  • Space Complexity: O(u) where u is number of unique users

Hardwood Species

Problem Information

  • Source: UVA
  • Difficulty: Secret
  • Time Limit: 3000ms
  • Memory Limit: 256MB

Problem Statement

A census of trees in a forest has been conducted. Given a list of tree species, calculate what percentage of the total forest each species represents. Output results in alphabetical order.

Input Format

  • First line: number of test cases
  • For each test case: list of tree names (one per line), separated by blank lines

Output Format

  • For each test case: each tree species followed by its percentage (4 decimal places)
  • Species listed in alphabetical order

Example

Input:
1

Red Alder
Ash
Ash
Red Alder
Red Alder

Output:
Ash 40.0
Red Alder 60.0

Total trees = 5. Ash appears 2 times (40%), Red Alder appears 3 times (60%).

Solution

Approach

Use dictionary to count occurrences of each tree species. Calculate percentage = (count / total) * 100. Sort keys alphabetically for output.

Python Solution
from collections import defaultdict


def solution():
  n = int(input())
  input()

  for _ in range(n):
    population = defaultdict(int)
    total = 0

    while True:
      try:
        line = input()
        if not line:
          break
      except:
        break
      population[line] += 1
      total += 1

    for tree in sorted(population):
      print(f"{tree} {round(population[tree] * 100 / total, 4)}")


solution()
Complexity Analysis
  • Time Complexity: O(n log n) for sorting species
  • Space Complexity: O(n) for dictionary

Bankrupt Baker

Problem Information

  • Source: UVA
  • Difficulty: Secret
  • Time Limit: 3000ms
  • Memory Limit: 256MB

Problem Statement

A baker has recipe binders with ingredients and recipes. Given a budget, find which recipes can be made within budget. Output affordable recipes sorted by cost (then alphabetically if tied).

Input Format

  • Number of binders
  • For each binder:
    • Binder name
    • m (ingredients), n (recipes), b (budget)
    • m lines of ingredient name and price
    • n recipes, each with name, number of ingredients, and ingredient quantities

Output Format

  • For each binder: binder name (uppercase), then affordable recipes sorted by cost then name, or “Too expensive!” if none affordable

Example

Input:
1
Desserts
3 2 10
flour 2
sugar 3
butter 5
Cake
2
flour 2
sugar 1
Cookies
2
butter 1
sugar 2

Output:
DESSERTS
Cake
Cookies

Cake costs 22 + 13 = 7, Cookies costs 15 + 23 = 11. With budget 10, only Cake is affordable initially, but let’s recalculate: Cookies = 5 + 6 = 11 > 10, so only Cake at cost 7 is shown.

Solution

Approach

Use dictionary to map ingredient names to prices. Calculate total cost for each recipe. Filter and sort recipes within budget.

Python Solution
def solution():
  binders = int(input())
  for _ in range(binders):
    binder_name = input().strip().upper()
    m, n, b = map(int, input().strip().split())

    ingredients = {}
    for _ in range(m):
      name, price = input().split()
      ingredients[name] = int(price)

    print(binder_name)
    affordable = []  # List of (cost, name) tuples for easy sorting

    for _ in range(n):
      recipe_name = input().strip()
      k = int(input())
      total_cost = 0
      for _ in range(k):
        name, quantity = input().split()
        total_cost += int(quantity) * ingredients[name]

      if total_cost <= b:
        affordable.append((total_cost, recipe_name))

    if not affordable:
      print('Too expensive!')
    else:
      affordable.sort()  # Sorts by cost first, then name
      for _, name in affordable:
        print(name)
    print()


solution()
Complexity Analysis
  • Time Complexity: O(B * (M + N * K + N log N)) where B is binders, M is ingredients, N is recipes, K is ingredients per recipe
  • Space Complexity: O(M + N)