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-2024 | http://sageshome.net/downloads/solutions...>> Time: 0.012s · Total: 2672320/2952264 |