Patrice T
Цитата:
Я читал об алгоритме Дейкстры, как вы можете использовать его в этой задаче?
Вы этого не сделаете, это не для такого рода проблем.
В таких конкурсах, как этот, это никогда не классическая задача, и хорошо известные решения не применяются.
В Примере 1 расстояние между 2 клавишами Маха
Геометрия такси-Википедия, свободная энциклопедия[
^].
Но когда клавиши повторяются, это не так,
вы должны разработать свой собственный алгоритм.
Алгоритм Дейкстры-Википедия, свободная энциклопедия[
^]
И вы должны быть осторожны с приведенными примерами:
6 4
AXYB
BBBB
KLMB
OPQB
DEFB
GHI*
AB
заявлено с лучшим решением 7 с:
Select Left Left Left Select Down Select
Но если вы это сделаете:
Select Down Select Left Down Select
или
Select Down Left Select Down Select
это 6
[Обновление]
Я только что закончил свою программу
Пример 2 еще хуже, я получаю 146 вместо 160.
Я наконец-то понял это, я пропустил
Если такого единичного квадрата нет, курсор не перемещается.
что делает некоторые ключи недоступными.
Моя вина.
[Обновление]
Вот мой код, но я боюсь, что у вас возникнут проблемы с его использованием, он написан на языке Clipper.
* https://online.acmicpc.org/problems/keyboard
procedure kb()
cls
* chargement des données
KB_init({"ABCDEFG", "HIJKLMN", "OPQRSTU", "VWXYZ**"}, "CONTEST")
KB_init({"12233445566778899000", "QQWWEERRTTYYUUIIOOPP", "-AASSDDFFGGHHJJKKLL*", "--ZZXXCCVVBBNNMM--**", "--------------------"}, "ACM-ICPC-WORLD-FINALS-2015")
KB_init({"ABCDEFGHIJKLMNOPQZY", "X*****************Y"}, "AZAZ")
KB_init({"AXYB", "BBBB", "KLMB", "OPQB", "DEFB", "GHI*"}, "AB")
return
procedure KB_init(clav, chn)
kb_max= (50+50)*10000
ltr= array(len(clav), len(clav[1]))
mat= array(len(clav), len(clav[1]))
cnt= array(len(clav), len(clav[1]))
for row=1 to len(clav)
afill(mat[row], .f.)
afill(cnt[row], kb_max)
for col=1 to len(clav[1])
ltr[row,col]= substr(clav[row],col,1)
next
? clav[row]
next
mat[1,1l]= .T.
cnt[1, 1]= 0
?
? chn
KB_propag(ltr, mat, cnt)
for scan=1 to len(chn)
touche= chn[scan]
KB_set(ltr, mat, cnt, touche)
KB_propag(ltr, mat, cnt)
* ? touche
best= kb_max
for row=1 to len(mat)
for col=1 to len(mat[row])
if ltr[row, col]= touche
best= min(best, cnt[row, col])
*?? cnt[row, col]
endif
next
next
* ?? best
* inkey(0)
next
* ? "*"
best= kb_max
for row=1 to len(mat)
for col=1 to len(mat[row])
if ltr[row, col]= "*"
best= min(best, cnt[row, col])
* ?? cnt[row, col]
endif
next
next
* ?? best
? best+ len(chn)+ 1
?
?
inkey(0)
return
procedure KB_set(ltr, mat, cnt, touche)
for row=1 to len(mat)
for col=1 to len(mat[row])
if ltr[row, col]= touche
mat[row, col]= .T.
else
mat[row, col]= .F.
cnt[row, col]= kb_max
endif
next
next
return
procedure KB_propag(ltr, mat, cnt)
* calculer la prochaine etape
boucle= .T.
do while boucle
boucle= .F.
for row=1 to len(mat)
for col=1 to len(mat[row])
if mat[row, col]
* est
if col < len(mat[row])
offset=1
do while col+ offset < len(mat[row]) .and. ltr[row, col]= ltr[row, col+ offset]
offset++
enddo
if ltr[row, col] != ltr[row, col+ offset]
if cnt[row, col+ offset] > cnt[row, col]+1
cnt[row, col+ offset] = cnt[row, col]+1
mat[row, col+ offset] = .T.
boucle= .T.
endif
endif
endif
* ouest
if col > 1
offset= -1
do while col+ offset > 1 .and. ltr[row, col]= ltr[row, col+ offset]
offset--
enddo
if ltr[row, col] != ltr[row, col+ offset]
if cnt[row, col+ offset] > cnt[row, col]+1
cnt[row, col+ offset] = cnt[row, col]+1
mat[row, col+ offset] = .T.
boucle= .T.
endif
endif
endif
* sud
if row < len(mat)
offset=1
do while row+ offset < len(mat) .and. ltr[row, col]= ltr[row+ offset, col]
offset++
enddo
if ltr[row, col] != ltr[row+ offset, col]
if cnt[row+ offset, col] > cnt[row, col]+1
cnt[row+ offset, col] = cnt[row, col]+1
mat[row+ offset, col] = .T.
boucle= .T.
endif
endif
endif
* nord
if row > 1
offset= -1
do while row+ offset > 1 .and. ltr[row, col]= ltr[row+ offset, col]
offset--
enddo
if ltr[row, col] != ltr[row+ offset, col]
if cnt[row+ offset, col] > cnt[row, col]+1
cnt[row+ offset, col] = cnt[row, col]+1
mat[row+ offset, col] = .T.
boucle= .T.
endif
endif
endif
mat[row, col]= .F.
endif
next
next
*
if boucle
boucle= .F.
for row= len(mat) to 1 step -1
for col= len(mat[row]) to 1 step -1
if mat[row, col]
* est
if col < len(mat[row])
offset=1
do while col+ offset < len(mat[row]) .and. ltr[row, col]= ltr[row, col+ offset]
offset++
enddo
if ltr[row, col] != ltr[row, col+ offset]
if cnt[row, col+ offset] > cnt[row, col]+1
cnt[row, col+ offset] = cnt[row, col]+1
mat[row, col+ offset] = .T.
boucle= .T.
endif
endif
endif
* ouest
if col > 1
offset= -1
do while col+ offset > 1 .and. ltr[row, col]= ltr[row, col+ offset]
offset--
enddo
if ltr[row, col] != ltr[row, col+ offset]
if cnt[row, col+ offset] > cnt[row, col]+1
cnt[row, col+ offset] = cnt[row, col]+1
mat[row, col+ offset] = .T.
boucle= .T.
endif
endif
endif
* sud
if row < len(mat)
offset=1
do while row+ offset < len(mat) .and. ltr[row, col]= ltr[row+ offset, col]
offset++
enddo
if ltr[row, col] != ltr[row+ offset, col]
if cnt[row+ offset, col] > cnt[row, col]+1
cnt[row+ offset, col] = cnt[row, col]+1
mat[row+ offset, col] = .T.
boucle= .T.
endif
endif
endif
* nord
if row > 1
offset= -1
do while row+ offset > 1 .and. ltr[row, col]= ltr[row+ offset, col]
offset--
enddo
if ltr[row, col] != ltr[row+ offset, col]
if cnt[row+ offset, col] > cnt[row, col]+1
cnt[row+ offset, col] = cnt[row, col]+1
mat[row+ offset, col] = .T.
boucle= .T.
endif
endif
endif
mat[row, col]= .F.
endif
next
next
endif
enddo
return