fork download
  1. import random
  2. import time
  3. import sys
  4.  
  5. sys.setrecursionlimit(10000)
  6.  
  7. # ------------------------
  8. # Генерація поля
  9. # 0 = поле ('.'), 1 = камінь ('#')
  10. # ------------------------
  11. def generate_field(N, M, p):
  12. grid = [[1 if random.random() < p else 0 for _ in range(M)] for _ in range(N)]
  13. grid[N-1][0] = 0
  14. grid[0][M-1] = 0
  15. return grid
  16.  
  17.  
  18. from collections import deque
  19. def exists_path_bfs(grid):
  20. N, M = len(grid), len(grid[0])
  21. start = (N-1,0)
  22. goal = (0, M-1)
  23. if grid[start[0]][start[1]] != 0 or grid[goal[0]][goal[1]] != 0:
  24. return False
  25. q = deque([start])
  26. vis = [[False]*M for _ in range(N)]
  27. vis[start[0]][start[1]] = True
  28. dirs = [(1,0),(-1,0),(0,1),(0,-1)]
  29. while q:
  30. r,c = q.popleft()
  31. if (r,c) == goal:
  32. return True
  33. for dr,dc in dirs:
  34. nr, nc = r+dr, c+dc
  35. if 0 <= nr < N and 0 <= nc < M and not vis[nr][nc] and grid[nr][nc] == 0:
  36. vis[nr][nc] = True
  37. q.append((nr,nc))
  38. return False
  39.  
  40. def longest_path_dfs(grid, time_limit=1.5, randomize=True):
  41. N, M = len(grid), len(grid[0])
  42. start = (N-1, 0)
  43. goal = (0, M-1)
  44. dirs = [(1,0), (0,1), (-1,0), (0,-1)]
  45. best_path = None
  46. best_len = -1
  47. start_time = time.time()
  48. max_nodes = 10**6
  49. nodes = 0
  50.  
  51. import random as _rnd
  52.  
  53. visited = [[False]*M for _ in range(N)]
  54. path = []
  55.  
  56. def dfs(r,c):
  57. nonlocal best_len, best_path, nodes
  58. if time.time() - start_time > time_limit:
  59. return
  60. nodes += 1
  61. if nodes > max_nodes:
  62. return
  63.  
  64. if (r,c) == goal:
  65. if len(path) > best_len:
  66. best_len = len(path)
  67. best_path = path.copy()
  68. return
  69.  
  70. neighs = []
  71. for dr,dc in dirs:
  72. nr, nc = r+dr, c+dc
  73. if 0 <= nr < N and 0 <= nc < M and not visited[nr][nc] and grid[nr][nc] == 0:
  74. dist = abs(nr - goal[0]) + abs(nc - goal[1])
  75. neighs.append((dist, nr, nc))
  76. neighs.sort(reverse=True, key=lambda x: x[0])
  77. if randomize:
  78. i = 0
  79. while i < len(neighs):
  80. j = i
  81. while j < len(neighs) and neighs[j][0] == neighs[i][0]:
  82. j += 1
  83. block = neighs[i:j]
  84. _rnd.shuffle(block)
  85. neighs[i:j] = block
  86. i = j
  87.  
  88. for _, nr, nc in neighs:
  89. if time.time() - start_time > time_limit:
  90. return
  91. visited[nr][nc] = True
  92. path.append((nr,nc))
  93. dfs(nr,nc)
  94. path.pop()
  95. visited[nr][nc] = False
  96. if grid[start[0]][start[1]] != 0 or grid[goal[0]][goal[1]] != 0:
  97. return None
  98.  
  99. visited[start[0]][start[1]] = True
  100. path.append(start)
  101. dfs(start[0], start[1])
  102. visited[start[0]][start[1]] = False
  103. path.pop()
  104.  
  105. return best_path
  106.  
  107. def print_board_numbered(grid, path):
  108. N, M = len(grid), len(grid[0])
  109. step = {}
  110. if path:
  111. for i, cell in enumerate(path):
  112. step[cell] = i
  113.  
  114. max_step = max(step.values()) if step else 0
  115. width = max(3, len(str(max_step)) + 2)
  116.  
  117. def cell_str(s):
  118. return str(s).center(width)
  119.  
  120. print()
  121. for r in range(N):
  122. row_cells = []
  123. for c in range(M):
  124. if (r,c) in step:
  125. row_cells.append(cell_str(step[(r,c)]))
  126. elif grid[r][c] == 1:
  127. row_cells.append(cell_str("#"))
  128. else:
  129. row_cells.append(cell_str("."))
  130. print("".join(row_cells))
  131. print()
  132. def main():
  133. print("=== Поля і каміння — пошук довгого простого шляху ")
  134. try:
  135. N = int(input("Введіть кількість рядків N (1..100): ").strip())
  136. M = int(input("Введіть кількість стовпців M (1..100): ").strip())
  137. except Exception:
  138. print("Некоректні N або M.")
  139. return
  140. if not (1 <= N <= 100 and 1 <= M <= 100):
  141. print("N і M повинні бути від 1 до 100.")
  142. return
  143.  
  144. try:
  145. p = float(input("Ймовірність каменю в клітинці (0..1), наприклад 0.25: ").strip())
  146. if not (0.0 <= p <= 1.0):
  147. raise ValueError()
  148. except Exception:
  149. print("Некоректне p — використовую 0.25")
  150. p = 0.25
  151.  
  152. try:
  153. tlim = float(input("Часовий ліміт пошуку в секундах (наприклад 1.5): ").strip())
  154. if tlim <= 0:
  155. tlim = 1.5
  156. except Exception:
  157. tlim = 1.5
  158.  
  159. regen = input("Якщо потрібно — згенерувати поле заново, якщо шляху немає? (т/н) [т]: ").strip().lower()
  160. regen_flag = (regen == "" or regen == "т" or regen == "y" or regen == "yes")
  161.  
  162. attempts = 0
  163. while True:
  164. attempts += 1
  165. grid = generate_field(N, M, p)
  166. if exists_path_bfs(grid):
  167. break
  168. if not regen_flag:
  169. break
  170. if attempts > 2000:
  171. print("Не вдалось згенерувати поле з шляхом за багато спроб. Спробуйте змінити p.")
  172. return
  173.  
  174. print("\nЗгенероване поле (вирівняне):")
  175. print_board_numbered(grid, None)
  176.  
  177. if not exists_path_bfs(grid):
  178. print("Шляху немає — завершую.")
  179. return
  180.  
  181. print(f"Починаємо пошук найдовшого простого шляху (таймаут = {tlim} сек)...")
  182. best = longest_path_dfs(grid, time_limit=tlim, randomize=True)
  183.  
  184. if not best:
  185. print("Не знайдено жодного шляху (неочікувано).")
  186. return
  187.  
  188. print(f"Знайдений шлях довжиною {len(best)} (0 = старт).")
  189. print("\nКарта з пронумерованим шляхом:")
  190. print_board_numbered(grid, best)
  191.  
  192. print("\nКроки шляху (1-based координати):")
  193. print([(r+1, c+1) for (r,c) in best])
  194.  
  195. if __name__ == "__main__":
  196. main()
  197.  
Success #stdin #stdout 1.6s 14308KB
stdin
25
25
0.25
1.5
т
stdout
=== Поля і каміння — пошук довгого простого шляху 
Введіть кількість рядків N (1..100): Введіть кількість стовпців M (1..100): Ймовірність каменю в клітинці (0..1), наприклад 0.25: Часовий ліміт пошуку в секундах (наприклад 1.5): Якщо потрібно — згенерувати поле заново, якщо шляху немає? (т/н) [т]: 
Згенероване поле (вирівняне):

 .  .  .  .  .  #  .  .  .  #  .  .  .  #  .  .  .  .  .  .  .  .  .  .  . 
 .  .  #  .  .  .  .  .  .  #  .  .  .  .  .  #  .  .  .  #  .  .  #  .  # 
 #  .  .  .  .  #  .  #  .  .  .  .  #  .  #  #  .  #  .  .  .  #  .  .  . 
 .  .  .  #  .  #  .  #  #  .  .  #  .  #  .  .  #  #  .  .  .  #  .  .  # 
 .  .  #  .  .  #  .  .  .  .  .  .  #  .  #  #  .  .  .  .  .  .  .  .  . 
 .  #  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  . 
 .  #  #  .  .  #  .  #  #  .  .  .  #  .  .  #  .  .  #  .  .  #  .  .  . 
 .  .  .  .  #  #  .  #  .  .  .  #  #  .  .  .  #  .  #  .  .  .  .  #  . 
 #  .  .  .  .  #  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  #  #  #  . 
 .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  #  .  #  #  #  .  . 
 .  .  .  #  #  #  .  #  .  #  .  .  #  #  .  #  .  .  .  .  .  .  .  #  # 
 .  .  #  .  .  .  .  #  #  .  .  .  .  .  #  .  .  .  #  .  #  .  .  .  . 
 .  .  #  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  #  .  .  .  .  #  # 
 .  .  .  #  .  #  #  #  .  .  .  .  .  .  .  #  .  .  .  #  .  .  .  #  . 
 .  .  .  .  .  .  #  #  .  .  .  .  .  .  #  #  .  .  #  .  #  .  .  .  . 
 #  .  #  .  .  #  .  .  #  #  .  .  .  .  #  .  .  .  .  .  #  #  #  .  . 
 .  .  #  #  .  .  .  #  #  .  .  .  .  .  .  .  #  .  #  .  .  .  .  #  . 
 .  .  #  .  .  .  .  .  .  #  .  #  .  #  .  #  #  .  .  .  .  .  .  .  . 
 #  #  #  .  .  .  #  .  .  .  .  .  #  .  .  #  #  .  .  #  #  .  .  .  . 
 .  .  #  .  .  .  .  .  .  #  .  .  .  .  #  .  .  #  .  #  .  .  .  .  . 
 .  .  #  .  .  .  #  .  .  .  .  .  #  #  .  .  .  .  #  .  #  .  .  .  . 
 .  .  .  .  #  #  .  .  .  .  .  .  .  #  .  .  .  .  .  .  .  .  #  .  . 
 #  .  .  #  .  .  #  #  .  .  #  .  .  .  .  .  .  .  .  #  .  #  .  #  . 
 .  .  .  .  .  .  .  .  .  .  .  #  .  .  #  #  .  #  .  #  .  .  .  .  . 
 .  .  .  .  #  #  #  #  #  .  #  .  .  .  .  .  #  .  .  #  #  .  .  .  # 

Починаємо пошук найдовшого простого шляху (таймаут = 1.5 сек)...
Знайдений шлях довжиною 297 (0 = старт).

Карта з пронумерованим шляхом:

 174  175  176  177   .    #    .    .    .    #   220  221  222   #   226  227  228   .    .    .   292  293  294  295  296 
 173  172   #   178  181  182  183   .    .    #   219  218  223  224  225   #   229  230  231   #   291   .    #    .    #  
  #   171   .   179  180   #   184   #    .   215  216  217   #    .    #    #    .    #   232  289  290   #   276  275   .  
 169  170   .    #    .    #   185   #    #   214  213   #    .    #    .    .    #    #   233  288  287   #   277  274   #  
 168   .    #    .    .    #   186  187  190  191  212   .    #    .    #    #    .    .   234  285  286  279  278  273  272 
 167   #    .    #   159  158  157  188  189  192  211  208  207  206  239  238  237  236  235  284  281  280  267  268  271 
 166   #    #   161  160   #   156   #    #   193  210  209   #   205  240   #    .    .    #   283  282   #   266  269  270 
 165  164  163  162   #    #   155   #    .   194   .    #    #   204  241  242   #    .    #    .   263  264  265   #    .  
  #   111  112  113   .    #   154  153   #   195  196  197   .   203  202  243   .   259  260  261  262   #    #    #    .  
 109  110   #   114  115  116  117  152  151  150  149  198  199  200  201  244  245  258   #    .    #    #    #    .    .  
 108  107   .    #    #    #   118   #    .    #   148   .    #    #    .    #   246  257   .    .    .    .    .    #    #  
 105  106   #    .    .    .   119   #    #    .   147  146  145  144   #   248  247  256   #    .    #    .    .    .    .  
 104   .    #    .    .    #   120  121  122  127  128  135  136  143   .   249  250  255   #    .    .    .    .    #    #  
 103   .    .    #    .    #    #    #   123  126  129  134  137  142   .    #   251  254   .    #    .    .    .    #    .  
 102  101  100   99   .    .    #    #   124  125  130  133  138  141   #    #   252  253   #    .    #    .    .    .    .  
  #    .    #    98   97   #    .    .    #    #   131  132  139  140   #    72   71   70   .    .    #    #    #    .    .  
  .    .    #    #    96   .    .    #    #    .    78   77   76   75   74   73   #    69   #    .    .    .    .    #    .  
  .    .    #    94   95   90   89   88   .    #    79   #    .    #    .    #    #    68   67   66   65   64   .    .    .  
  #    #    #    93   92   91   #    87   86   .    80   .    #    .    .    #    #    .    .    #    #    63   .    .    .  
  .    .    #    14   15   18   19   20   85   #    81   .    .    .    #    .    .    #    .    #    .    62   .    .    .  
  .    .    #    13   16   17   #    21   84   83   82   .    #    #    .    .    .    .    #    .    #    61   60   59   .  
  .    10   11   12   #    #    .    22   23   28   29   30   .    #    39   40   .    44   45   46   47   .    #    58   57 
  #    9    8    #    .    .    #    #    24   27   #    31   32   37   38   41   42   43   .    #    48   #    .    #    56 
  1    2    7    6    .    .    .    .    25   26   .    #    33   36   #    #    .    #    .    #    49   50   53   54   55 
  0    3    4    5    #    #    #    #    #    .    #    .    34   35   .    .    #    .    .    #    #    51   52   .    #  


Кроки шляху (1-based координати):
[(25, 1), (24, 1), (24, 2), (25, 2), (25, 3), (25, 4), (24, 4), (24, 3), (23, 3), (23, 2), (22, 2), (22, 3), (22, 4), (21, 4), (20, 4), (20, 5), (21, 5), (21, 6), (20, 6), (20, 7), (20, 8), (21, 8), (22, 8), (22, 9), (23, 9), (24, 9), (24, 10), (23, 10), (22, 10), (22, 11), (22, 12), (23, 12), (23, 13), (24, 13), (25, 13), (25, 14), (24, 14), (23, 14), (23, 15), (22, 15), (22, 16), (23, 16), (23, 17), (23, 18), (22, 18), (22, 19), (22, 20), (22, 21), (23, 21), (24, 21), (24, 22), (25, 22), (25, 23), (24, 23), (24, 24), (24, 25), (23, 25), (22, 25), (22, 24), (21, 24), (21, 23), (21, 22), (20, 22), (19, 22), (18, 22), (18, 21), (18, 20), (18, 19), (18, 18), (17, 18), (16, 18), (16, 17), (16, 16), (17, 16), (17, 15), (17, 14), (17, 13), (17, 12), (17, 11), (18, 11), (19, 11), (20, 11), (21, 11), (21, 10), (21, 9), (20, 9), (19, 9), (19, 8), (18, 8), (18, 7), (18, 6), (19, 6), (19, 5), (19, 4), (18, 4), (18, 5), (17, 5), (16, 5), (16, 4), (15, 4), (15, 3), (15, 2), (15, 1), (14, 1), (13, 1), (12, 1), (12, 2), (11, 2), (11, 1), (10, 1), (10, 2), (9, 2), (9, 3), (9, 4), (10, 4), (10, 5), (10, 6), (10, 7), (11, 7), (12, 7), (13, 7), (13, 8), (13, 9), (14, 9), (15, 9), (15, 10), (14, 10), (13, 10), (13, 11), (14, 11), (15, 11), (16, 11), (16, 12), (15, 12), (14, 12), (13, 12), (13, 13), (14, 13), (15, 13), (16, 13), (16, 14), (15, 14), (14, 14), (13, 14), (12, 14), (12, 13), (12, 12), (12, 11), (11, 11), (10, 11), (10, 10), (10, 9), (10, 8), (9, 8), (9, 7), (8, 7), (7, 7), (6, 7), (6, 6), (6, 5), (7, 5), (7, 4), (8, 4), (8, 3), (8, 2), (8, 1), (7, 1), (6, 1), (5, 1), (4, 1), (4, 2), (3, 2), (2, 2), (2, 1), (1, 1), (1, 2), (1, 3), (1, 4), (2, 4), (3, 4), (3, 5), (2, 5), (2, 6), (2, 7), (3, 7), (4, 7), (5, 7), (5, 8), (6, 8), (6, 9), (5, 9), (5, 10), (6, 10), (7, 10), (8, 10), (9, 10), (9, 11), (9, 12), (10, 12), (10, 13), (10, 14), (10, 15), (9, 15), (9, 14), (8, 14), (7, 14), (6, 14), (6, 13), (6, 12), (7, 12), (7, 11), (6, 11), (5, 11), (4, 11), (4, 10), (3, 10), (3, 11), (3, 12), (2, 12), (2, 11), (1, 11), (1, 12), (1, 13), (2, 13), (2, 14), (2, 15), (1, 15), (1, 16), (1, 17), (2, 17), (2, 18), (2, 19), (3, 19), (4, 19), (5, 19), (6, 19), (6, 18), (6, 17), (6, 16), (6, 15), (7, 15), (8, 15), (8, 16), (9, 16), (10, 16), (10, 17), (11, 17), (12, 17), (12, 16), (13, 16), (13, 17), (14, 17), (15, 17), (15, 18), (14, 18), (13, 18), (12, 18), (11, 18), (10, 18), (9, 18), (9, 19), (9, 20), (9, 21), (8, 21), (8, 22), (8, 23), (7, 23), (6, 23), (6, 24), (7, 24), (7, 25), (6, 25), (5, 25), (5, 24), (4, 24), (3, 24), (3, 23), (4, 23), (5, 23), (5, 22), (6, 22), (6, 21), (7, 21), (7, 20), (6, 20), (5, 20), (5, 21), (4, 21), (4, 20), (3, 20), (3, 21), (2, 21), (1, 21), (1, 22), (1, 23), (1, 24), (1, 25)]