Результаты проверки задач из билетов к экзамену по курсу "Алгоритмы и алгоритмические языки (2010/2011 уч.гг.)."

За решения задач выставлялись оценки (в порядке убывания):
+
+.
+-
+/2
-+
-

Причем, принципиальной разницы между первыми двумя оценками, по существу, нет.
Сами задачи можно найти здесь. В задачах я своих комментариев почти не оставлял. Они нужны только для того, чтобы соотнестись с написанным ниже.
У вас есть пара дней на уточнение неясных моментов в оценке задач. Пока не обсуждается вопрос о том, как оценка за задачу влияет на оценку за экзамен. Это - следующий этап.
Все вопросы по оценкам можно посылать по адресу staroverovvl@yandex.ru.
Заранее приношу извинения за свои возможные ошибки, возникшие при переносе моих комментариев в html, в результате которого какие-то отдельные симовлы могли стать неудобоваримами. Я все проверял, но, наверняка, что-то пропустил.
01_23. +-
В целом, похоже на правду. Общая направленность правильная. Хотя, недочетов очень много.
Параметры надо было вводить с командной строки (т.е. надо было использовать параметры main).
Не понравился вызов
malloc((n+k)*sizeof(int *));
здесь n и к относятся к объектам разных типов (а размеры их могут быть разными!).
Логичнее бы было
malloc(n*sizeof(int *)+k*sizeof(int)); Формула для вычисления k, конечно, тоже не верная: при n=1 получаем:
tmp=sqrt(8.0*n+9.0);//=sqrt(17.)
k=(int)tmp;//=4
k=(k-3)/2;//=0
Я бы здесь не мучился, а просто посчитал бы требуемое k в цикле.
Длина строки должна быть по условию = k%m+1 , а у вас она = k+1
Проверки на возможность ввода fscanf(fin, "%d", &val); нет, хотя уверенности в правильном вычислении k у вас, думаю, тоже не было.

02_04. +/2
Задача посложнее, чем предполагалось при программировании. Кроме констант 'a', 'b', 'c' еще бывают константы '\n', '\t', '\'', а еще '\011'. Т.е. в задаче надо было брать все между одинарными кавычками, игнорируя кавычки после обратного слеша.

03_05. -
Кто-то писал мне письмо по этой задаче, и я подробно отвечал на него. Жаль, что этот мой ответ не дошел до всех. Решение принципиально не правильное. С бинарными файлами надо работать по-другому, чем с текстовыми. открывать файлы надо "wb" и "rb", иначе вводиться будет не всегда то, что лежит в файле. Считывать/записывать надо функциями fread/fwrite.
Но даже с точки зрения текстового ввода/вывода решение бессмысленно. Например, написано
fscanf(f1, "%s", data)
где data описывается как
char data[2];
И на что можно рассчитывать?

04_22. +
В качестве придирки: вместо
for (i=0;(fscanf(in, "%d", &x)==1)&&(i<kolvo);i++)masiv[i]=x;
qsort(masiv,kolvo,sizeof(int),task_04_bilet22_compare);

следовало бы написать
for (i=0;(fscanf(in, "%d", &x)==1)&&(i<kolvo);i++)masiv[i]=x;
kolvo=i;
qsort(masiv,kolvo,sizeof(int),task_04_bilet22_compare);

иначе бессмысленно проверять на возможность ввода.

05_14. +-
В целом, все очень не плохо. НО.
Я КАТЕГОРИЧЕСКИ запрещал использование функции feof()!!! Более того, я обещал сразу ставить двойку, если увижу у кого эту функцию. Я не буду еще раз объяснять, что конструкция
while(!feof(innums))
неправильная.

Основная проблема: целое разделить на целое дает целое, а у вас предполагается, что результат - вещественное. Из-за этого программа работать не будет.
Неправильно вычисляется сумма элементов:
m+=temp->znam/temp->chisl;
вместо этого надо
m+=((double)temp->znam)/temp->chisl;
Неправильно производится сравнение:
if(fabs(temp->znam/temp->chisl-m)<=(float)(1/N))
вместо этого надо
if(fabs(((double)temp->znam)/temp->chisl-m)<=(double)(1./N))

06_15. +-
Первое впечатление: программа слишком сложно написана, чтобы она работала.
Второе впечатление: при проверке на тестах выясняется, что программа работает правильно.
Третье впечатление: настораживают циклы:
if (cnt1 < i*step+step/2)
{
for (j = cnt1; j < i*step+step/2; j++)
arrtmp[cnttmp++] = arr[j];
}
if (cnt2 < (i+1)*step && cnt2 < cnt)
{
for (j = cnt2; j < (i+1)*step; j++)
arrtmp[cnttmp++] = arr[j];
}

В них нет проверки выхода за границу массива (например, (i+1)*step может выйти за границу массива).
Четвертое впечатление: на длинном массиве программа, все же, падает. Например, у меня программа упала на вот таком массиве (можно проверить, что во втором цикле происходит выход за границу массива)
5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 3 5 2 8 4 1 0 9 0 0 0 0 1 1 1 1 1 10 1 01

07_03. +.
Неправильно:
if(string=strstr(string,"#define "))
вместо strstr должно стоять strcmp, т.к. директива #define может встречаться только в начале
строки (или после пробелов).
Остальное хорошо.

08_12. +
ОЧЕНЬ хотел хоть к чему-то придраться, но не смог :-)
09_06. -
Программа не компилируется: 4-тый параметр fun имеет тип double , а в него передается const char * .

10_10. -
Прогамма не компилируется:

10_19main.cpp(35) : error C2065: 'task_10_19_sort' : undeclared identifier
10_19main.cpp(35) : error C2113: pointer can only be subtracted from another pointer
10_19main.cpp(36) : error C2113: pointer can only be subtracted from another pointer
10_19main.cpp(44) : error C2373: 'task_10_19_sort' : redefinition; different type modifiers


11_21. +-
Вообще-то программа должна упасть на больших массивах. Следующая строка неправильная:
t=(list*)realloc(t,k);
должно быть:
t=(list*)realloc(t,k*sizeof(list));
Так же неверно:
k=task_11_21(fx,argv[1]);
здесь fx не инициализирется.
Ф-ция main должна возвращать int, а у вас она ничего не возвращает.

12_21. -
Выражение неправильно дважды:
if(tmp1->m-x<=1/n)
должно быть:
if(fabs(tmp1->m-x)<=1./n)
А самое главное: память под структуры не отводится!!! Вся работа производится в ОДНОЙ структуре. Посему программа не работает, если во входном файле более одного числа. Также в самом начале неправильно
scanf(f,"%f",&x);
из чего сразу следует вывод, что программа вообще не тестировалась.
13_10. +
Все хорошо, только при выводе fprintf следует после формата пробел вставлять:
fprintf(f2,"%d ",tek->a);
fprintf(f2,"%d ",tek->b);

, иначе все слепляется и на выводе все переменные идут без разделения.

14_11. +-
В формулировке задачи просилось имена файлов передавать через параметры main, а не вводить с клавиатуры.
Использование malloc() внутри функции сортировки замедляет работу функции настолько, что делает алгоритм бессмысленным. Отведенная в функции память не очищается. Строка
tmp = (int)ceil((double)nach+kon1)/2;
достаточно бессмысленна. То же самое можно написать гораздо проще:
tmp = (nach+kon1)/2;

15_06. -
Может, я чего-то не понял? Реализации функции, решающей задачу, я в тексте не нашел.

16_02. -+
В функции сначала впустую считывается весь файл, а потом в выходной файл записывется не более одного слова. Достаточно проверить работу программы на файле с самой программой, чтобы понять, что программа не работает.
Использовать fscanf(f,"%s"...) для считывания текста довольно бессмысленно. Про причину я рассказывал.

17_09. -
Кто-то писал мне письмо по этой задаче, и я подробно отвечал на него. Жаль, что этот мой ответ не дошел до всех. Решение принципиально не правильное. С бинарными файлами надо работать по-другому, чем с текстовыми. открывать файлы надо "wb" и "rb", иначе вводиться будет не всегда то, что лежит в файле. Считывать/записывать надо функциями fread/fwrite.

18_15. +-
Использование malloc() в функции сортировки делает алгоритм бессмысленным, т.к. эта функция очень медленна.
Функция free(C); вызвается ПОСЛЕ фигурной скобки, а должна ДО. Посему память очищается не до конца.

19_17. +-
В задаче вместо требуемого проверяется другое условие: проверяется, каких строк больше: в которых больше нулевых пикселов, или в которых больше единичных пикселов. Это - совсем не то, что требуется в задаче.

20_07. -+
В следующей строке происходит выход за границы массива (за грницы отведенной памяти):
k=m[i];
В следующей строке происходит приравнивание, а не сравнение:
if(m[i]=k)
Итого: программа распечатает все элементы массива, кроме нулевых.

21_23. +-
В программе вообще не присутствует ни одного двумерного массива в виде указателя на указатель, как требуется в условии. Тем не менее, все остальное программа делает. Формально надо ставить -, но т.к. на выходе, тем не менее, получается все правильно, то поставлю +-

22_2. +-
Для адекватного считывания текста нельзя использовать функцию fscanf(). Если вы протестируете свою программу, то поймете, почему. В остальном все хорошо.

23_19. -
При компиляции выдается 16 ошибок. Текст достаточно бессмысленен.

24_5. -
Кто-то писал мне письмо по этой задаче, и я подробно отвечал на него. Жаль, что этот мой ответ не дошел до всех. Решение принципиально не правильное. С бинарными файлами надо работать по-другому, чем с текстовыми. открывать файлы надо "wb" и "rb", иначе вводиться будет не всегда то, что лежит в файле. Считывать/записывать надо функциями fread/fwrite.

25_03. +-
Для адекватного считывания текста нельзя использовать функцию fscanf(). Директива #define может стоять только в начале строки, что вы не учитывает, поэтому если на вход вашей программе подать файл вашей программы, то на выходе неожиданно появится
f=1;
В остальном все хорошо.

26_13. -
Кто-то писал мне письмо по этой задаче, и я подробно отвечал на него. Жаль, что этот мой ответ не дошел до всех. Решение принципиально не правильное. С бинарными файлами надо работать по-другому, чем с текстовыми. открывать файлы надо "wb" и "rb", иначе вводиться будет не всегда то, что лежит в файле. Считывать/записывать надо функциями fread/fwrite.

27_10. -+
Вообще-то программа не компилируется. После исправления синтаксической ошибки замечаем, что переотведение памяти сделано неправильно: вместо
mn=(list*)realloc(mn,k);
надо
mn=(list*)realloc(mn,k*sizeof(list));
Т.е. при большом количестве исходных данных программа упадет.

28_18. +
В целом, все хорошо. Не нравится ошибка, которая встречается у многих:
m=(int*)malloc(n*sizeof(int));
while (fscanf(f1, "%d", &a)==1)
{
m[i]=a;
i++;
}
Лучше:
m=(int*)malloc(n*sizeof(int));
for(i=0;i<n&&fscanf(f1, "%d", m+i)==1;i++);
n=i;
В вашем случае если данных больше, чем задано в первом числе, то программа упадет.

29_12. +

30_04. -+
Не верно:
if (argc>=1) task_30_04(argv[1], argv[2]);
должно быть:
if (argc>2) task_30_04(argv[1], argv[2]);
Вообще, программа делает что-то не то, хотя текст осмысленный. В ней зачем-то ищутся ключевые слова const и char, причем они могут идти не подряд. В программе вообще не рассматривается вариант текстовых констант `\0', '\t' и т.п. Для считывания текста используется fscanf(), что не правильно (я рассказывал почему).

31_09. +

32_01. +-
Использовать fscanf для адектватного считывания текста нельзя (я рассказывал почему; можете глянуть во что превращается ваш же исходный файл при обработке вашей же программой). Все остальное очень похоже на правду.

33_11. +
Конструкция неправильная:
char *in, *out;
...
scanf("%s",in);
scanf("%s",out);
о чем компилятор сразу же и говорит. Память надо отводить!
Все остальное хорошо.

34_03. -
6 ошибок компиляции.
35_20. +
Все очень хорошо.
36_16. +-
Все правильно, но в условии просилось отводить память всего два раза (хотя, все можно сделать и при одном вызове). Естественно, что при этом придется прочитать файл дважды.

37_13. +.
Есть две ошибки:
Следующая строка не делает то, что вами предполагается:
int k= (int)arr[2];
вместо этого должно быть что-то типа:
int k; sscanf(arr[2],"%d",&k);
Также забыто, что файл out.bmp надо перебросить в исходный файл.

38_07. +
Все очень хорошо. Только, по правилам хорошего тона, в языке C имена обычных переменных пишутся строчными буквами (в прописными в начале смысловых слов), а имена #define-констант только прописными. Если вы привыкли не следовать этому правилу, то у вас, как минимум, будут проблемы, когда будете работать в команде.

39_01. -
Программа при компиляции выдает 5 ошибок.

40_18. +
Все очень хорошо

41_17. +-
Ой, путаница какая-то у вас... В следующем цикле значение t не изменяется:
for (i=0;i<128;i++)
{
if (t) countOne++;
else countZero++;
}
и что мы считаем?
В следующей строке
fwrite("1",1,1,fOut);
записывается не 1 а код символа `1'. А это - не то, что требуется.