6 ноября 1995г. я удосужился выиграть школьную олимпиаду Железнодорожного района
(города Н-ска, естественно) по информатике. Легко. Не могу сказать, что там были интересные
или сложные задания - подзадач такой и большей степени сложности по несколько штук в любой
более-менее серьезной программе.
На олимпиаде, конечно, дело в том, чтобы решить несколько абсолютно разных
и непонятно откуда взявшихся задач за 2 часа в неидеальной для думания обстановке
гонки.
К сожалению, из-за недооценки преподавателем моих
возможностей мне не довелось попасть на городскую олимпиаду и показать и там, где проводят
холодное время года эти самые земноводные... ну, которые еще свистят вечно -
залезут повыше, и глушат всех.
Программы портировались с Yamaha MSX-2 (MSX-BASIC) на QBASIC и назад,
поэтому не используют нормальных операторов управления типа LOOP и т. д.
Первые три задачи - собственно орудие победы (сейчас смотрю: ну и что в них такого?)
Остальные были решены в процессе моральной подготовки.
Если вы хотите попробовать эти программы на "Ямахе", можно использовать
оригинальные MSX-версии программ (они есть только для трех олимпиадных),
либо портировать "перебранные" программы с QBASIC.
Для портирования программ назад на MSX нужно: проставить номера строк, заменить
текстовые метки на соответствующие номера; заменить SELECT CASE
на ON... GOTO, "собрать" многострочные конструкции
IF... THEN... ELSE... END IF в однострочные
IF... THEN... ELSE... В основном, на этом различия и заканчиваются
(программы перенесены с минимальной модификацией).
Кстати, есть способ запустить программы для MSX под Windows - использовать
какой-либо MSX Emulator.
Решить головоломку (A, B, C - с клавиатуры):
???
x ??
------
A???
B???
????C
Выдать все возможные решения.
INPUT "Enter A, B, C: ", a, b, c
m1 = a * 1000
x1 = m1 + 999
m2 = b * 1000
x2 = m2 + 999
FOR x = 111 TO 999
FOR y1 = 1 TO 9
s1 = y1 * x
IF NOT (s1 < m1 OR s1 > x1 OR (s1 MOD 10 <> c)) THEN
FOR y2 = 1 TO 9
s2 = y2 * x
s = s2 * 10 + s1
IF s < 99999! AND s2 >= m2 AND s2 <= x2 THEN
PRINT "-----"
PRINT USING " ###"; x
PRINT USING " ##"; y1 + y2 * 10
PRINT USING " ####"; s1
PRINT USING "#### "; s2
PRINT USING "#####"; s
END IF
NEXT
END IF
NEXT
NEXT
Определить, является ли введенная фраза палиндромом (т. е., читающейся задом наперед точно так же, например: "Ленин ел", "А роза упала на лапу Азора", "Аргентина манит негра").
LINE INPUT "Кандидат в палиндромы? "; p$
l$ = "абвгдежзийклмнопрстуфхцчшщъыьэюя"
u$ = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
m$ = " :,.+-;*?/\|~'`!@#$^&()[]{}%=" + CHR$(34)
FOR t = 1 TO LEN(p$)
q$ = MID$(p$, t, 1)
ln = INSTR(l$, q$)
IF ln > 0 THEN q$ = MID$(u$, ln, 1) ELSE IF INSTR(m$, q$) > 0 THEN q$ = ""
a1$ = a1$ + q$: a2$ = q$ + a2$
NEXT
IF a1$ = a2$ THEN PRINT "Палиндром!" ELSE PRINT "Не палиндром."
INPUT "Число"; x
PRINT "Простые множители"; x; ":"
os = x
newdiv:
IF os = 1 THEN PRINT : END
IF os MOD 2 = 0 THEN os = os / 2: PRINT 2; : GOTO newdiv
FOR k = 3 TO os / 3 STEP 2
IF os MOD k = 0 THEN os = os / k: PRINT k; : GOTO newdiv
NEXT
PRINT os
Заменить "?" на знаки арифметических операций так, чтобы получилось верное равенство.
Не самое красивое решение - с использованием функций
было бы гораздо лучше... Но в MSX-BASIC возможности определения функций
крайне ограничены. Отличие QBASIC-версии от оригинала в использовании SELECT CASE
вместо ON...GOTO.
' ((((1?2)?3)?4)?5)?6=36
DIM s(5), t$(4)
t$(1) = "+": t$(2) = "-": t$(3) = "/": t$(4) = "*"
FOR s1 = 1 TO 4: s(1) = s1
FOR s2 = 1 TO 4: s(2) = s2
FOR s3 = 1 TO 4: s(3) = s3
FOR s4 = 1 TO 4: s(4) = s4
FOR s5 = 1 TO 4: s(5) = s5
a = 1
FOR i = 1 TO 5
j = i + 1
SELECT CASE s(i)
CASE 1: a = a + j
CASE 2: a = a - j
CASE 3: a = a / j
CASE 4: a = a * j
END SELECT
NEXT
IF a = 36 THEN
PRINT "36=((((1"; t$(s1); "2)"; t$(s2); "3)";
PRINT t$(s3); "4)"; t$(s4); "5)"; t$(s5); "6"
END IF
NEXT s5, s4, s3, s2, s1
INPUT "Введите складываемые числа (a, b)"; s1$, s2$
IF LEN(s1$) < LEN(s2$) THEN SWAP s1$, s2$
s2$ = STRING$(LEN(s1$) - LEN(s2$), "0") + s2$
PRINT : PRINT : PRINT " "; s1$: PRINT "+ "; s2$
FOR i = LEN(s1$) TO 1 STEP -1
ri = ASC(MID$(s1$, i, 1)) + ASC(MID$(s2$, i, 1)) - ASC("0") * 2 + pe
pe = ri \ 10
ri = ri MOD 10
r$ = MID$(STR$(ri), 2, 1) + r$
NEXT
PRINT "=";
IF pe > 0 THEN r$ = MID$(STR$(pe), 2, 1) + r$ ELSE PRINT " ";
PRINT r$
INPUT "Число корней? ", n
DIM a(n), x(n), t(n)
FOR i = 0 TO n - 1
PRINT "x("; i; ")";
INPUT x(i)
NEXT
a(0) = 1
FOR st = 0 TO n - 1
t(0) = 0
FOR i = 0 TO st: t(i + 1) = a(i): NEXT
FOR i = 0 TO st: t(i) = t(i) - a(i) * x(st): NEXT
FOR i = 0 TO st + 1: a(i) = t(i): NEXT
NEXT
PRINT "Уравнение:"
FOR i = n TO 1 STEP -1
IF a(i) > 0 THEN
PRINT "+("; a(i); "* X ^"; i; ")";
ELSE
IF a(i) < 0 THEN PRINT "-("; -a(i); "* X ^"; i; ")";
END IF
NEXT
IF a(0) <> 0 THEN PRINT "+("; a(0); ")";
PRINT "=0"
Выдает таблицу всех возможных перестановок n элементов.
INPUT "Число элементов? ", n
DIM a(n), in(n), p(n): i = 1
FOR w = 1 TO n: a(w) = w: NEXT
NEWFOR: in(i) = 1
CHKFOR: IF in(i) > n THEN IF i = 1 THEN END ELSE i = i - 1: RETURN
IF p(in(i)) = 1 THEN GOTO NEXTFOR
IF i = n THEN GOSUB SHOW: i = i - 1: RETURN
p(in(i)) = 1
i = i + 1: GOSUB NEWFOR
p(in(i)) = 0
NEXTFOR: in(i) = in(i) + 1: GOTO CHKFOR
SHOW:
FOR w = 1 TO n: PRINT USING "####"; a(in(w)); : NEXT
x$ = INPUT$(1)
PRINT
RETURN
Выдает все возможные разложения целого числа на слагаемые. Со слишком большими числами какие-то проблемы - резко падает быстродействие (?)
INPUT "Раскладываемое число? ", n
DIM s(n), m(n): m(1) = n: i = 1
NEWFOR: s(i) = 1
CHKFOR: IF s(i) = m(i) THEN
GOSUB SHOW
IF i = 1 THEN END ELSE i = i - 1: RETURN
END IF
m(i + 1) = m(i) - s(i)
i = i + 1: GOSUB NEWFOR
s(i) = s(i) + 1: GOTO CHKFOR
SHOW:
FOR w = 1 TO i - 1
IF s(w + 1) > s(w) THEN RETURN
NEXT
PRINT n; "="; s(1);
FOR w = 2 TO i: PRINT "+"; s(w); : NEXT: PRINT
RETURN
| © Sergey A. Galin, 1998-2026 | http://sageshome.net/downloads/solutions...>> Time: 0.012s · Total: 3185174/3465118 |