N
× M
grid ( N
and M
up to 500) is applied to the input. Each cell of the grid contains either ' .
'- open cell, or' #
'- closed cell ("blocked by car"). The goal is to construct a path of maximum length (“a queue of people”) along open cells from the upper left corner so that every cell of the path (except the initial one) is to the right or below from the previous one. 5 5 5 ..... ..... ..... ..... ..... 1 10 .......... 5 5 ...#. ...#. ...#. ...#. ..... 3 3 ..# #.# ... 3 8 ........ #.#.#.#. #.#.#.#.
Case #1: 17 Case #2: 10 Case #3: 17 Case #4: 5 Case #5: 10
↓→↓. ↓↑↓.. ↓↑↓.. ↓↑↓.. →↑→→⊕
→→→→→→→↓ #.#.#.#↓ #.#.#.#⊕
:- table queue(+, +, +, +, +, +, max). queue(_R, _C, _, _, X, Y, 1) :- \+ car(X, Y). % move down queue(R, C, Used, Prev, X, Y, S) :- X < R, Prev \= up, Xp1 is X + 1, \+ car(Xp1, Y), queue(R, C, Used, down, Xp1, Y, Snext), S is 1 + Snext. % move right queue(R, C, Used, Prev, X, Y, S) :- Y < C, Prev \= left, Yp1 is Y + 1, \+ car(X, Yp1), queue(R, C, Used, right, X, Yp1, Snext), S is 1 + Snext. % move up queue(R, C, Used, Prev, X, Y, S) :- X > 1, (Used =:= 0 ; Prev == up), Prev \= down, Xm1 is X - 1, \+ car(Xm1, Y), queue(R, C, 1, up, Xm1, Y, Snext), S is 1 + Snext. % move left queue(R, C, Used, Prev, X, Y, S) :- Y > 1, (Used =:= 0 ; Prev == left), Prev \= right, Ym1 is Y - 1, \+ car(X, Ym1), queue(R, C, 1, left, X, Ym1, Snext), S is 1 + Snext. do_case(Case_num, R, C) :- queue(R, C, 0, right, 1, 1, S), format("Case #~w: ~w\n", [Case_num, S]). main :- read(T), foreach(Case_num in 1..T, [R, C, N], ( initialize_table, abolish, read([R, C]), read(N), assert(car(-1, -1)), % dummy foreach(_I in 1..N, [X, Y], (read([X, Y]), assert(car(X, Y)))), do_case(Case_num, R, C) )).
queue
: the first 6 parameters are input, and the last is output, and it needs to be maximized if several different output values are possible for any input parameters.queue
:R
- the number of rows in the gridC
- the number of columns in the gridUsed
- 1 if the movement to the left or up has already been used, otherwise 0Prev
- direction in the previous stepX
- current X-coordinateY
- current Y-coordinateS
is the path length from ( X
, Y
).queue
states that if a cell ( X
, Y
) is not blocked by a car, then a queue of length 1 (at least) with a start in that cell is possible.X
less than the number of rows in the R
gridX+1
, Y
) is not blocked by the carX+1
, Y
).(Used =:= 0 ; Prev == up)
.do_case
uses queue
to find the maximum queue length starting in the upper left corner. Thanks to tabulation, the results for subtasks are calculated only once.main
reads the number of tests, and for each test it reads the R
, C
and positions of the cars in a format convenient for Prolog; for each vehicle, a fact is added to the Prolog fact base for subsequent use by the queue
predicate rules. T = int(raw_input()) print "%d." % T for case_num in range(1, T + 1): R, C = map(int, raw_input().split()) print "[%d, %d]." % (R, C) cars = [] for i in range(R): row = raw_input().strip() for j in range(C): if row[j] == '#': cars.append([i + 1, j + 1]) print "%d." % len(cars) for car in cars: print "[%d, %d]." % (car[0], car[1])
tail
removes the B-Prolog version message from the results): cat in-file | python preprocess.py | bp -g "cl('AAAAAA.pl'),main,halt" -l | tail -n +7 > out-file
Source: https://habr.com/ru/post/246657/
All Articles