М И Н И СТ Е РСТ В О О Б РА ЗО В А Н И Я РО ССИ Й СК О Й Ф Е Д Е РА Ц И И В О РО Н Е Ж СК И Й ГО СУ Д А РСТ В Е Н Н ЫЙ У Н И В Е РСИ Т Е Т
О .Ф .У скова О .Д .Гор бенко А .И .Ш аш кин
О ЛИ М П И А Д Н ЫЕ ЗА Д А ЧИ П О П РО Г РА М М И РО В А Н И Ю . ЛУ ЧШ И Е РЕ Ш Е Н И Я Часть2
У чебное издание
В О РО Н Е Ж – 2001
Б Б К 32.97 У Д К 681.3 О ли м п и ад н ы е зад ачи п о п рограм м и рован и ю . Л у чш и е ре ш е н и я. В тре х частях. Часть 2.: У че бн ое и зд ан и е / О .Ф .У скова, О .Д .Горбе н к о, А.И.Ш аш ки н – В орон е ж: О О О ПФ «Д жу д и », 2001 – 44 с.
Работа вы п олн е н а в рам ках Ф е д е ральн ой це ле вой п рограм м ы «Ин те граци я» п о н ап равле н и ю «В оссозд ан и е сту д е н че ск и х н ау чн ы х ш к ол и оли м п и ад » (п рое к тР0054). Изд ае тся п ри фи н ан совойп од д е ржке О О О ПФ «Д жу д и ».
Б Б К 32.97 У Д К 681.3 ISBN 5-815-047-0 © В орон е жск и й у н и ве рси те т © Ф е д е ральн ая це ле вая п рограм м а «Ин те граци я» © О .Ф .У ск ова, О .Д .Горбе н ко, А.И.Ш аш к и н © О О О ПФ «Д жу д и »
О ГЛ А В Л Е Н И Е Пре д и слови е . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1. О бщ ая и н форм аци я о ш коле -оли м п и ад е . . . . . . . . . . . . . . . . . . . . . . . . . .4 2. Зад ачи ск ом м е н тари ям и и ре ш е н и ям и . . . . . . . . . . . . . . . . . . . . . . . . . . .
П Р Е Д И СЛО В И Е И з д ание п од г от овле но в рам ках п рое кт а Р 0054 Ц е ле вой Ф е д е ральной п рог рам м ы
"И нт е г рация"
по
нап равле нию
"Воссоз д ание
ст уд е нч е ских
науч ны х ш кол и олимп иад ". Оно орие нт ировано в основном на уч аст ников р егио н а л ь н о й
о т кр ы т о й
ст уден ческо й
ш ко л ы -о л им пиа ды
пр о гр а м м ир о ва н ию и ко м пь ю т е р н о м у м о дел ир о ва н ию , но м оже т т акже
по бы т ь
п оле з но ш кольникам ст арш их классов, ст уд е нт ам и уч ит е лям
информат ики общ е образ оват е льны х и п рофильны х уч е бны х з аве д е ний . О рг аниз ат орам и
ш колы -олимп иад ы
являют ся
Вороне жский
г осуниве рсит е т , Вы ч ислит е льны й Ц е нт р Р оссий ской Акад е м ии Наук (РАН) и Вороне жский г осуд арст ве нны й п е д аг ог ич е ский униве рсит е т . В п е рвой ч аст и рассм ат ривались з ад ач и п ре д ш е ст вовавш их олимп иад п о информат ике раз лич ног о уровня (факульт е т ских, вуз овских, м е жвуз овских, ре г иональны х, фе д е ральны х). Не кот оры е з ад ач и п риве д е ны с ре ш е ниям и, в
основном
раз работ анны ми
ст уд е нт ам и
факульт е т а
п риклад ной
м ат е м ат ики и м е ханики Вороне жског о униве рсит е т а, ст авш им и в свое вре мя п риз е рам и эт их олим п иад . Во вт орой
ч аст и п ом им о з ад ач ,
п ре д ложе нны х на олим п иад ах раз лич ног о уровня, п ре д ст авле ны м ат е риалы п е рвог о (з аоч ног о) т ура ш колы -олим п иад ы . Вороне жский
униве рсит е т , на баз е
кот орог о п ровод ит ся ш кола-
олим п иад а, вы ражае т п риз нат е льност ь О О О ПФ "Джуд и" (д ире кт ор Анд ре й .Василье вич Анд ре й ч иков), оказ авш е м у се рье з ную п од д е ржку в из д ании эт ой книг и.
1. О Б Щ А Я И Н Ф О РМ А Ц И Я О Ш К О ЛЕ -О ЛИ М П И А Д Е П О ЛО Ж Е Н И Е О П Е РВ О М Т У РЕ Пе рвы й ту р ш колы -оли м п и ад ы состои тся 17 се н тября 2001 год а. Е го п ре д у см отре н о п рове сти в те ле к ом м у н и каци он н ом ре жи м е . Е сли ву з н е п од клю че н к Ин те рн е ту , то п олу чи тьзад ан и я м ожн о од н и м и з сп особов: 1. Л и чн о яви ться в О ргком и те т ш к олы -оли м п и ад ы ком н .8)
(У н и ве рси те тск ая п л., 1,
2. О брати ться в бли жайш и й Ин те рн е т-салон (н ап ри м е р, н а главн ы е п очтовы е отд е ле н и я) 3. При слать заявк у н а вы д ачу зад ан и я п о эле к трон н ой п очте
[email protected] .
п о ад ре су
Ф и ли алы у н и ве рси те та (Л и ски , В е рхн и й М ам он , С тары й О скол) п олу чат зад ан и я че ре з п ре д стави те ле й у н и ве рси те та н а м е стах, в свои ху че бн ы х отд е лах. Н а п е рвом ту ре бу д у т п ре д ложе н ы 2 зад ачи : п е рвая - общ ая, вторая у чи ты ваю щ ая сп е ци альн ость у частн и к ов оли м п и ад ы . К рассм отре н и ю п ри н и м аю тся работы , в которы х ре ш е н а хотя бы од н а зад ача. О ргком и те т п ре д у п ре жд ае т, что совп ад аю щ и е д ру г с д ру гом с точн остью д о ле ксе м ы п рограм м ы рассм атри ваться н е бу д у т. Ре ш е н и я д олжн ы бы ть вы слан ы п о эле ктрон н ой п очте п о ад ре су
[email protected] , ли бо п ре д ставле н ы ли чн о в О ргком и те т ш колы -оли м п и ад ы (У н и ве рси те тская п л., 1, к ом н .8) д о 17 часов 19 се н тября 2001 год а. В сам ом н ачале п рограм м ы в каче стве ввод н ого ком м е н тари я н е обход и м о у казать сле д у ю щ и е све д е н и я: - фам и ли ю , и м я, отче ство автора (п олн остью ); - п ре д ставляе м ы й ву з; - ад ре сву за;
- факу льте т; - сп е ци альн ость(сп е ци али заци ю ); - форм а обу че н и я (ве че рн яя, заочн ая); - фам и ли ю , и м я, отче ство и у че н ое зван и е д е кан а факу льте та ; - фам и ли ю , и м я, отче ство и у че н ое зван и е п ре п од авате ля, которого автор счи тае тсвои м тре н е ром (е сли такойе сть); - д ом аш н и й ад ре савтора п рограм м ы ; - e-mail, URL, ICQ. О ргк ом и те тбу д е трассм атри ватьработы тольк о сту д е н тов ву зов. В п е рвом ту ре у стан авле н ы сле д у ю щ и е н ом и н аци и д ля у частн и ков: - сту д е н ты 1 к у рса (н е зави си м о отсп е ци альн ости ); - сту д е н ты , д ля которы х и н форм ати ка являе тся п рофи ли ру ю щ е й д и сци п ли н ой (сп е ци альн ости - п ри клад н ая м ате м ати ка, м ате м ати ка, м е хан и ка, фи зи ка, ком п ью те рн ы е н ау ки , С А ПР, и н форм ати ка, вы чи сли те льн ы е си сте м ы , си сте м н ое п рограм м и рован и е , эк он ом и ка, эк он ом и че ск ая ки бе рн е ти ка, и н форм аци он н ы е си сте м ы , и н форм аци он н ая бе зоп асн ость) ; сту д е н ты , д ля которы х и н форм ати ка являе тся общ е образовате льн ой д и сци п ли н ой; - сту д е н ты гу м ан и тарн ы х сп е ци альн осте й; - сту д е н ты , сп е ци али зи ру ю щ и е ся в области и ску сства, к у льту ры , сп орта. По же лан и ю сту д е н ты 1 ку рса м огу т п е ре йти в н ом и н аци ю , отве чаю щ у ю и х сп е ци альн ости . ЗА Д А Н И Я
1 Т У РА
З ад ач а (общ ая д ля все х н ом и н аци й) Н а острове BORLAND кажд ы й и з е го жи те ле й орган и зовал п арти ю , котору ю сам и возглави л. В кажд ой п арти и – н е м е н е е д ву х че лове к. По К он сти ту ци и острова в п арлам е н т д олжн ы войти главы все х п арти й, н о фи н ан совы е тру д н ости н е п озволяю т это сд е лать. Н а ре фе ре н д у м е гражд ан е острова ре ш и ли , что к ажд у ю п арти ю в п арлам е н те д остаточн о п ре д ставлять од н и м чле н ом п арти и . Т ре бу е тся сформ и ровать п арлам е н т как м ожн о м е н ьш е й чи сле н н ости , в котором бы ли бы п ре д ставле н ы все п арти и . Т е хн и че ски е тре бован и я. В се главы п арти й(и п арти и ) п е ре н у м е рован ы от1 д о N (41) and not zan do begin i:=i-1; j:=j-1; zan:=doc[i,j] end; i:=x; j:=y; { просмотр правой диагонали }
while (i>1) and (jm_ptr == NULL) { DBG(("Trying to free memory more than once in 'free_vect': vect=%p\n", vect)); return; }; free(vect->m_ptr); vect->m_ptr=NULL;
vect->m_size=0; DBG(("Successful call to 'free_vect': vect=%p\n",vect)); } /* Получение указателя на элемент вектора */ VECT_BASETYPE* at_vect(unsigned int x, struct t_vect *vect) { /* проверка корректности аргументов */ if (x >= vect->m_size) { DBG(("Error calling 'at_vect': x=%u, vect>m_size=%u\n",x, vect->m_size)); return NULL; }; DBG(("Successful call to 'at_vect': x=%u, vect=%p\n",x,vect)); return &vect->m_ptr[ x ]; } struct t_matr { MATR_BASETYPE *m_ptr; unsigned int m_xsize, m_ysize; }; /* Создание новой матрицы. Входные данные: x,y --- размеры матрицы Выходные данные: matr --- матрица Примечание: начальное значение всех элементов равно 0; если память под матрицу уже выделена, она не освобождается */ int alloc_matr(unsigned int x, unsigned int y, struct t_matr *matr) { /* проверка корректности входных данных */ if ((x==0) || (y==0)) { DBG(("Error calling 'alloc_matr': x=%u, y=%u\n",x,y)); return ERR_PARAM; }; /* выделение памяти */ matr->m_ptr = calloc(sizeof(MATR_BASETYPE), x*y); matr->m_xsize = x; matr->m_ysize = y; /* проверка */ if ( matr->m_ptr == NULL ) { DBG(("Error allocating memory in 'alloc_matr': x=%u, y=%u\n",x,y)); return ERR_MEMORY; }; DBG(("Successful call to 'alloc_matr': x=%u, y=%u, matr=%p\n",x,y,matr)); return ERR_OK; } /* Удаление старой матрицы */ void free_matr(struct t_matr *matr) { if (matr->m_ptr == NULL) { DBG(("Trying to free memory more than once in 'free_matr': matr=%p\n", matr)); return; }; free(matr->m_ptr); matr->m_ptr=NULL;
matr->m_xsize=0; matr->m_ysize=0; DBG(("Successful call to 'free_matr': matr=%p\n",matr)); } /* Получение указателя на элемент "двумерной" матрицы */ MATR_BASETYPE* at_matr(unsigned int x, unsigned int y, struct t_matr *matr) { /* проверка корректности аргументов */ if ((x >= matr->m_xsize) || (y >= matr->m_ysize)) { DBG(("Error calling 'at_matr': x=%u, y=%u, matr>m_xsize=%u, matr->m_ysize=%u\n",x,y, matr->m_xsize, matr->m_ysize)); return NULL; }; DBG(("Successful call to 'at_matr': x=%u, y=%u, matr=%p\n",x,y,matr)); return &matr->m_ptr[ y*matr->m_xsize + x ]; } /* ===== Работа с файлами ===== */ /* чтение исходных данных. Входные данные: filename --- имя файла Выходные данные: matr --- матрица принадлежности граждан партиям */ int ReadInput (const char *filename, struct t_matr *matr) { FILE *fh; unsigned int N; unsigned int ibuffer; int i; int result; char buffer[10000]; char *cur_pos; int offset; fh=fopen(filename, "r"); /* проверка результата */ if (fh == NULL) { DBG(("Error opening file in 'ReadInput': filename=%s\n",filename)); return ERR_FILE; }; if (fscanf(fh,"%u",&N) != 1) { DBG(("Error reading table size in 'ReadInput': filename=%s\n",filename)); fclose(fh); return ERR_FILEFORMAT; }; /* выделение новой матрицы */ alloc_matr(N,N,matr); fgets(buffer, 10000, fh); for (i=0; im_size-1; (*at_vect(i,vect))++; while ((*at_vect(i,vect) > n-1) && (i>0)) { (*at_vect(i-1,vect))++; i--; };
for (; i+1m_size; i++) { *at_vect(i+1,vect) = *at_vect(i,vect)+1; }; if (*at_vect(i,vect) < n) return ERR_OK; return ERR_FAILED; } int TestCombination(struct t_matr *matr, struct t_vect *vect) { int x,p; struct t_vect excluded; int excl_size; alloc_vect(matr->m_xsize,&excluded); excl_size=0; for (p=0; pm_size; p++) { for (x=0; x<matr->m_xsize; x++) { if (*at_matr(x,*at_vect(p,vect),matr)) { if (!*at_vect(x,&excluded)) { excl_size++; (*at_vect(x, &excluded)) ++; }; }; }; }; free_vect(&excluded); if (excl_size < matr->m_xsize) { return ERR_FAILED; } else { return ERR_OK; }; } int SolvePrecise(struct t_matr* matr, struct t_vect* vect) { int k,i; alloc_vect(matr->m_ysize, vect); for (k=1; k<matr->m_ysize; k++) { vect->m_size=k; for (i=0; im_ysize, k, vect) == ERR_OK); }; vect->m_size=0; DBG(("Successful call to 'Solve'; no solution found!\n")); return ERR_FAILED; } int CalcMarks(struct t_matr *matr, struct t_vect *vect, struct t_vect *excl) { int x,y;
int max, imax; max=0; imax=0; for (y=0; y<matr->m_ysize; y++) { for (x=0; x<matr->m_xsize; x++) { if (*at_vect(x,excl) == 0) { *at_vect(y,vect) += *at_matr(x,y,matr); if (*at_vect(y,vect) > max) { max=*at_vect(y,vect); imax=y; }; }; }; }; return imax; } int Solve(struct t_matr* matr, struct t_vect* vect) { struct t_vect marks, excluded; unsigned int excl_num; int i,pos; int solve_size; alloc_vect(matr->m_ysize, vect); alloc_vect(matr->m_ysize, &marks); alloc_vect(matr->m_xsize, &excluded); excl_num=0; solve_size=0; while (excl_num < matr->m_xsize) { for (i=0; i<marks.m_size; i++) *at_vect(i,&marks)=0; pos=CalcMarks(matr, &marks, &excluded); *at_vect(solve_size, vect)=pos; solve_size++; for (i=0; i<matr->m_xsize; i++) { if (*at_matr(i,pos,matr)) { if (!*at_vect(i,&excluded)) { excl_num++; }; (*at_vect(i,&excluded))++; }; }; }; vect->m_size = solve_size; free_vect(&excluded); free_vect(&marks); DBG(("Successful call to 'Solve'\n")); return ERR_OK; } /* ===== входная точка программы ===== */ int main(int argc, char *argv[]) { struct t_matr matr; struct t_vect solution; ReadInput("input.txt",&matr); if (matr.m_xsize > 60) {
Solve(&matr, &solution); } else { SolvePrecise(&matr, &solution); }; free_matr(&matr); WriteOutput("output.txt",&solution); free_vect(&solution); return ERR_OK; }
Задача11. " П ер еселение" Задача предлагалась на первом (заочном)туре Открытой региональной студенческой школы-олимпиады по программированию и компьютерному моделированию 17-19 сентября 2001 года. Автор решения: Козлов Юрий Станиславович, один из призеров первого тура олимпиады, студент 1 курса РТФ ВИ МВД РФ 16гр Н а К ом п ью те рн ой у ли це жи ву т в собстве н н ы х д ом ах тольк о се м ьи Паскалё вы х и С и п лю сп лю совы х. О н и ре ш и ли п е ре се ли ться так , чтобы все Паскалё вы жи ли в н ачале у ли цы , а все С и п лю сп лю совы - в к он це . Изве стн о общ е е коли че ство д ом ов н а у ли це и кто жи ве т в кажд ом д ом е . Т ре бу е тся разработать м од е ль и алгори тм (п рограм м у ) п е ре се ле н и я, п ри у слови и , что кажд ая се м ья д олжн а п е ре е зжатьн е боле е од н ого раза, а в кажд ом обм е н е д олжн ы у частвовать только д ве се м ьи .
Uses Crt,Dos; const n=30; delayy=200;{ =x do begin if Text[y][x]=index then begin case y of 1:textcolor(LightRed); 2:textcolor(LightGreen); 3..5:textcolor(LightGray); 6..9:textcolor(Yellow); 10:textcolor(Green); 11,12:textcolor(LightGray); 13,14:textcolor(LightBlue); 15..17:textcolor(LightRed); end; gotoxy(ctx+x,cty+y); write(text[y][x]);
delay(delayy div 4); end; x:=x+1; end; end; end; GotoXY(80,25); ReadLn; TextBackGround(Black); TextColor(LightGray); ClrScr; End; Procedure change(a1,b1:integer); {меняет местами два элемента массива street} begin if street[a1]=0 then begin street[b1]:=0; street[a1]:=1; end; end; Begin ClrScr; Randomize; Introduction; for i:=1 to n do street[i]:=random(2); {случайное заполнение улицы} street2:=street; s:=0; left:=0; right:=0; write(' '); For i:=1 to n do begin if street[i]=1 then textcolor(LightRed) else TextColor(yellow); write(street2[i],' '); end; writeln; writeln; for i:=1 to n do if street[i]=1 then s:=s+1;{считаем общее число 1} for i:=1 to s do if street[i]=1 then left:=left+1;{определяем к какому краю} for i:=n-s+1 to n do if street[i]=1 then right:=right+1;{рациональнее } if left>=right then begin i:=0; j:=n+1; a:=1; b:=-1; q:=sleft;end{премещать} else begin i:=n+1; j:=0; a:=-1;b:=1; q:=s-right; end;{} for f:=1 to q do begin repeat i:=i+a; until street[i]=0;{находим крайний нолик} repeat j:=j+b; until street[j]=1;{находим крайнюю единичку} change(i,j); {меняем их местами} textcolor(LIghtgreen); write(f,') '); For k:=1 to n do begin {выводим полученное на экран} if street[k]=1 then textcolor(LightRed) else textcolor(Yellow); write(street[k],' '); end; Writeln; end; TextColor(LightRed); GotoXY(56,24);Write('1');TextColor(Yellow); write(' - Семья Паскалёвых'); GotoXY(56,25); write('0');TextColor(LightRed); write(' - Семья Сиплюсплюсовых');TextColor(LightGray); GotoXy(2,25);Write('Press');TextColor(DarkGray); Write(' any key');TextColor(LightGray); write(' to exit.'); i:=1;j:=1;
Repeat i:=i+1; if i mod 10000 = 0 then begin j:=j+1; if j mod 2 = 0 then textcolor(white) else textcolor(darkgray); i:=1; end; GotoXy(8,25);write('any key'); Until keypressed; ReadKey; {нажимаем any key для выхода} End.
Авторы : д оц. О .Ф .У скова, д оц. О .Д .Горбе н к о, п роф. А.И.Ш аш ки н Ре д ак тор – Л .А.Ан д ре йчи кова
О ли м п и ад н ы е зад ачи п о п рограм м и рован и ю . Л у чш и е ре ш е н и я. В тре х частях. Часть 2.: У че бн ое и зд ан и е / О .Ф .У скова, О .Д .Горбе н ко, А.И.Ш аш ки н – В орон е ж: О О О ПФ «Д жу д и », 2001 – 64 с. О тп е чатан о в О О О ПФ «Д жу д и », ти раж. 200 экз.