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 14340KB
stdin
25
25
0.25
1.5
т
stdout
=== Поля і каміння — пошук довгого простого шляху (забезпечує, що фініт останній) ===
Введіть кількість рядків N (1..100): Введіть кількість стовпців M (1..100): Ймовірність каменю в клітинці (0..1), наприклад 0.25: Часовий ліміт пошуку в секундах (наприклад 1.5): Якщо потрібно — згенерувати поле заново, якщо шляху немає? (т/н) [т]: 
Згенероване поле (вирівняне):

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

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

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

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


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