Advertisement
LilChicha174

Untitled

Jan 14th, 2025
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.57 KB | None | 0 0
  1. #Условие задачи
  2. #Мы в Авито любим проводить соревнования, — недавно мы устроили чемпионат по шагам. И вот настало время подводить итоги!
  3.  
  4. #Необходимо определить userIds участников, которые прошли наибольшее количество шагов steps за все дни, не пропустив ни одного дня #соревнований.
  5.  
  6. #Пример
  7. #Ввод
  8. statistics = [
  9.     [{ 'userId': 1, 'steps': 1000 }, { 'userId': 2, 'steps': 1500 }],
  10.     [{ 'userId': 2, 'steps': 1000 }],
  11. ]
  12. #Вывод
  13. champions = { 'userIds': [2], 'steps': 2500 }
  14.  
  15.  
  16. #Ввод
  17. statistics = [
  18.     [{ 'userId': 1, 'steps': 2000 }, { 'userId': 2, 'steps': 1500 }],
  19.     [{ 'userId': 2, 'steps': 4000 }, { 'userId': 1, 'steps': 3500 }],
  20. ]
  21. #Вывод
  22. champions = { 'userIds': [1, 2], 'steps': 5500 }
  23.  
  24. #Ввод
  25. statistics = []
  26. #Вывод
  27. champions = { 'userIds': [], 'steps': 0 }
  28.  
  29. #Главная идея — как только понимаем, что пользователь пропустил день, мы тут же перестаём его «тащить» дальше в памяти. Это поможет #особенно в случаях, когда много пользователей пропускает соревнования, и лишь немногие доходят «до конца».
  30.  
  31. #Как работает
  32. #На первом дне собираем всех участников в множество valid_users и сразу же запоминаем их шаги.
  33.  
  34. #На каждом следующем дне:
  35.  
  36. #Собираем всех участников этого дня во временный словарь day_map вида {userId: steps_за_день}.
  37. #Делаем пересечение valid_users с day_map.keys(). Те, кого нет в текущем дне, сразу «отваливаются» из дальнейшего рассмотрения (они уже #не могут быть чемпионами, раз пропустили).
  38. #Для оставшихся «валидных» пользователей прибавляем их шаги в общий счётчик.
  39. #В конце у нас останутся только те, кто не пропустил ни единого дня. Суммарные шаги для них уже посчитаны.
  40.  
  41. #За счёт «проредивания» множества valid_users мы избавляемся и от лишних записей в total_steps.
  42.  
  43. #Временная сложность
  44. #Проход по всем дневным записям (в сумме m штук) даёт O(m).
  45. #Дополнительно на каждом дне делается пересечение valid_users &= day_map.keys().
  46. #Если в среднем множества небольшие или сильно «режутся» на каждом шаге, это может быть довольно быстро.
  47. #В худшем случае пересечение двух множеств размером u занимает
  48. #O(u), но суммарно всё равно остаётся в рамках
  49. #O(m) с некоторой константой на операции с множествами.
  50.  
  51. def find_champions_optimized(statistics):
  52.     n = len(statistics)
  53.     if n == 0:
  54.         return {"userIds": [], "steps": 0}
  55.    
  56.     # Берём все userId из первого дня как "пока ещё валидные"
  57.     first_day = statistics[0]
  58.     valid_users = set(record["userId"] for record in first_day)
  59.    
  60.     # Словарь для суммарных шагов только по тем, кто ещё валиден
  61.     total_steps = {}
  62.     for record in first_day:
  63.         total_steps[record["userId"]] = total_steps.get(record["userId"], 0) + record["steps"]
  64.    
  65.     # Последовательно обрабатываем оставшиеся дни
  66.     for day in statistics[1:]:
  67.         # Словарь шагов для пользователей конкретного дня
  68.         day_map = {}
  69.         for record in day:
  70.             uid = record["userId"]
  71.             day_map[uid] = day_map.get(uid, 0) + record["steps"]
  72.        
  73.         # «Узкий проход»: пересекаем множество "валидных" с участниками текущего дня
  74.         valid_users &= day_map.keys()
  75.        
  76.         # Чтобы не хранить в total_steps "мертвые" userId, удаляем их
  77.         # (тех, кто вылетел, больше не понадобится считать)
  78.         for user in list(total_steps.keys()):
  79.             if user not in valid_users:
  80.                 del total_steps[user]
  81.        
  82.         # Для оставшихся прибавляем шаги
  83.         for user in valid_users:
  84.             total_steps[user] = total_steps.get(user, 0) + day_map[user]
  85.    
  86.     # Если в итоге никто не остался, значит все кто-то пропустил
  87.     if not valid_users:
  88.         return {"userIds": [], "steps": 0}
  89.    
  90.     # Ищем максимум шагов среди уцелевших
  91.     max_steps = max(total_steps[user] for user in valid_users)
  92.     # Собираем всех, у кого шаги = максимум
  93.     champions = [user for user in valid_users if total_steps[user] == max_steps]
  94.    
  95.     return {"userIds": champions, "steps": max_steps}
  96.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement