Разбирали как-то со школьниками такую задачу по программированию. Найти все шестизначные целые числа, которые
а) делятся на 5;
б) состоят из различных цифр (ни одна цифра в записи числа не встречается дважды);
в) четные и нечетные цифры чередуются.
Алгоримт приходит в голову сразу. Нужно перебирать числа от 100000 до 999999 с шагом 5. Каждое число разложить на цифры. Затем проверять условия б) и в), и если они выполнены, печатать число.
Разложение на цифры тривиально даже для школьника. Проверка на разлиные цифры в числе реализуется двойным циклом, где каждая цифра сравнивается со следующими. Проверка на чередование еще проще: одним проходом по массиву цифр сравниваем четности двух соседних. В общем, на Фортране программа получается такая
! Разложить число на цифры
subroutine decompose(n,A)
implicit none
integer n,A(*)
integer r,i
r = n
do i=6,1,-1
A(i) = mod(r,10)
r = r/10
end do
end subroutine decompose
! Все цифры различны
logical function test1(A,n)
implicit none
integer n
integer A(*)
integer i,j
do i=1,n-1
do j=i+1,n
if (A(j).eq.A(i)) then
test1 = .false.
return
end if
end do
end do
test1 = .true.
end function test1
! Четные и нечетные чередуются
logical function test2(A,n)
implicit none
integer A(*)
integer n
integer i
do i=1,n-1
if (mod(A(i),2) .eq. mod(A(i+1),2)) then
test2 = .false.
return
end if
end do
test2 = .true.
end function test2
! Основная программа
program Main
implicit none
interface
subroutine decompose(n,A)
implicit none
integer n,A(*)
end subroutine decompose
logical function test1(A,n)
implicit none
integer A(*)
integer n
end function test1
logical function test2(A,n)
implicit none
integer n
integer A(*)
end function test2
end interface
integer n,A(6),count
count = 0
do n=100000, 999999, 5
call decompose(n,A)
if (test1(A,6).and.test2(A,6)) then
count = count + 1
write (3,*) n
end if
end do
write (*,*) count
end
Обратите внимание, что в подпрограммах test1 и test2 выход производится при первом же несовпадении, т.е. изнутри циклов, для чего используется оператор return. Попробуем теперь записать то же самое на учебном Е-языке (система "Кумир"). Там есть оператор выход, но если он расположен внутри цикла, то производит выход только из непосредственно охватывающего цикла. Поэтому в Тест1 приходится во внешнем цикле после внутреннего проверять, по какой причине завершился этот внутренний, и если он заврешился досрочно, то завершать и внешний. Получается некрасиво.
алг
нач
цел n,count
цел таб A[1:6]
count := 0
нц для n от 100000 до 999999 шаг 5
Цифры(n,A)
если Тест1(6,A) и Тест2(6,A) то
count := count + 1
вывод n, нс
все
кц
вывод нс, count
кон
алг лог Тест1 (арг цел n, цел таб A[1:n])
нач
цел i,j
лог fail
нц для i от 1 до n-1
нц для j от i+1 до n
fail := A[j] = A[i]
если fail то
выход
все
кц
если fail то
выход
все
кц
знач := не fail
кон
алг лог Тест2 (арг цел n, цел таб A[1:n])
нач
цел i
лог fail
нц для i от 1 до n-1
fail := mod(A[i],2) = mod(A[i+1],2)
если fail то
выход
все
кц
знач := не fail
кон
алг Цифры(арг цел n, рез цел таб A[1:6])
нач
цел r,i
r := n
нц для i от 6 до 1 шаг -1
A[i] := mod(r,10)
r := div(r,10)
кц
кон