Кадндидат-студентски изпит по информатика на C++

С++ решаваня на задачи по информатика, от кандидатстудентски изпити

Изпит по информатика в ПУ, 2 юни 2009

leave a comment »

Решение на С++ на задача 1, дадена на кандидатстудентския изпит в ПУ на 2 юли 2009г.

Условие:

Да се състави компютърна програма за обслужване на национално състезание по
лека атлетика за мъже и жени, в което участват до 100 състезатели от различни отбори.
Всички състезатели са родени преди 2000 г. За целта:

  1. За всеки участник да се въведе следната информация:
    • ЕГН (десетцифрен единен граждански номер);
    • име (знаков низ до 40 знака, състоящ се от две или повече подимена, разделени с точно един интервал);
    • име на отбор (знаков низ до 20 знака);
    • дисциплина (знаков низ до 25 знака);
    • място в класирането по съответната дисциплина (цяло число).
  2. Да се изведе списък на всички състезатели, съдържащ последно име на участник, име на отбор, дисциплина и място в класирането. Списъкът трябва да бъде подреден по име на отбор (в азбучен ред), а за един и същи отбор по място в класирането(възходящо). Полетата да бъдат разделени със запетая и един интервал. Например:
    Николов, Спартак-Плевен, хвърляне на копие, 1
  3. Да се изведе списък на всички участници, класирани до трето място включително от отбора Спартак-Плевен. Списъкът трябва да бъде подреден по име на участник и да съдържа име на участник, име на отбор, дисциплина и място в класирането.
  4. Да се въведе информация за три национални състезания по лека атлетика като се контролира броят на участниците да не надхвърля 100. За всяко от тях да се изведат справките от точки 2 и 3 и се отпечатат имената на състезателките, родени след 20.08.1988, като се знае, че първите 2 цифри от ЕГН-то определят годината, втората двойка цифри – месеца, третата двойка – деня на раждане, а на жените деветата цифра
    от ЕГН-то е нечетна. Например за ЕГН 7510210094 датата на раждане е 21.10.1975 г., а полът е женски (тъй като 9 е нечетно).

Решение на С++:

/*
 ============================================================================
 Name        : pu_2009_1.cpp
 Author      : Ivan Stoyanov
 Version     :
 Copyright   : Stoqnoff
 Description : Решнение на задача 1 на вариант 2 от предварителния кандидат-
               студентски изпит по информатика в Пловдивски университет даван,
               на 2 юни 2009 г.
 ============================================================================
 */
#include<iostream>
#include<cstring>

using namespace std;

// Декларират се помощни функциии
/* Проверява рожденната дата от егн-то, дали е по-ранна от зададената (880820) */
bool checkBirdDate(const char *egn, const char *date);
/* Проверява дали атлета е жена, по зададено егн */
bool isFemale(const char *egn);
/* Връща последната дума (думата след последния интервал). */
const char * getLastWord(const char *string, const char *word);


// Структура, описваща даден атлет
struct Athlete
{
	char egn[11];
	char name[41];
	char team[21];
	char discipline[26];
	int place;
};

/* Въвежда атлет */
void inputAthlete(Athlete &);
/* Извежда атлет на екрана */
void displayAthlete(Athlete const &, bool);
/* Намира фамилията на атлет, която се връща в параметъра family */
const char * getAthleteFamily(Athlete const &, const char *family);

// Структура, описваща списък с атлети
struct AthleteList
{
	int count;
	Athlete athletes[100];
};

/* Инициализира списъка с атлети */
void initAthletes(AthleteList &);
/* Добавя атлет към списъка с атлети */
void addAthleteToList(AthleteList &, Athlete const &);
/* Въвежда атлети в списъка */
void inputAthletes(AthleteList &);
/* Сортира списъка с атлети по тим (и резултат) */
void sortAthletesByTeamAndResult(AthleteList &);
/* Сортира списъка с атлети по име на атлет */
void sortAthletesByName(AthleteList &);
/* Извежда списъка с атлети на екрана */
void displayAthletes(AthleteList const &, bool);
/* Извежда имената на жените родени след дадена година */
void displayFemaleAthletes(AthleteList const &list, const char *afterDate);
/* Връща списък с атлети, които са медалисти */
AthleteList getMedalistsAthletes(AthleteList const &);


/* Главна функция на програмата */
int main()
{
	AthleteList athletes, medalists;

	for(int i=1; i<=3; i++) {

		std::cout << "Sastezanie " << i << ".\n";
		std::cout << "-----------------------------------------------------------------\n\n";

		// Инициализира празен списък
		initAthletes(athletes);
		// Въвеждат се данни в списъка с атлети
		inputAthletes(athletes);

		// Сортира се списъкът по отбор
		sortAthletesByTeamAndResult(athletes);
		// Извежда се сортираният списък с атлети
		std::cout << "Athletes list: " << "\n\n";
		displayAthletes(athletes, false);

		// Намира се списъкът с медалистите
		medalists = getMedalistsAthletes(athletes);
		// Медалистите се сортират по имената на участниците
		sortAthletesByName(medalists);

		// Извежда се сортираният списък с медалисти
		std::cout << "Athletes list in 1-3 place: " << "\n\n";
		displayAthletes(athletes, false);

		// Извежда имената на жените родени след 20.08.1988
		std::cout << "Female athletes born after 20.08.1988: " << "\n\n";
		displayFemaleAthletes(athletes, "880820");
	}

	return 0;
}


/* Проверява рожденната дата от егн-то, дали е по-ранна от зададената (880820) */
bool checkBirdDate(const char  *egn, const char *date)
{
	char birdDate[7];
	// Копира първите 6 символа от egn в birdDate
	strncpy(birdDate, egn, 6);

	// Сравнява лексикографски двете дати
	int cmp = strcmp(birdDate, date);
	if( cmp <= 0 ) return false;
	return true;
}

/* Проверява дали атлета е жена, по зададено егн */
bool isFemale(const char *egn)
{
	if ( (egn[8]-'0')%2 == 1 ) return true;
	return false;
}


/*
  Връща последната дума (думата след последния интервал).
  Резултата се връща в низа word
  Решението се реализира с указатели защото е по-лесно да се
  работи с такива когато има обработка на низове.
 */
const char  * getLastWord(const char *str, const char *word)
{
	int length=strlen(str);
	// Указател се позиционира до последния символ в низа
	char *namePtr =(char *) str + (length-1);

	// указателясе насочва към първия интервал срещнат от зад напред
	// като се проверява за всеки случай дали не е достигнат края на низа
	int i=0;
	while(' '!=*namePtr && i++<=length) namePtr--;

	// Позицията на низовия указател е насочена към интервала, затова
	// се копира низа с начло от следващия символ след интервала
	strcpy((char *)word, namePtr+1);
	return (const char  *)word;
}

/* Въвежда атлет */
void inputAthlete(Athlete &athlete)
{
	std::cout << "Input egn: ";
	std::cin.getline(athlete.egn, 41);

	std::cout << "Input name: ";
	std::cin.getline(athlete.name, 41);

	std::cout << "Input team: ";
	std::cin.getline(athlete.team, 21);

	std::cout << "Input discipline: ";
	std::cin.getline(athlete.discipline, 26);

	std::cout << "Input place: ";
	std::cin >> athlete.place;

	char dummy[1024];
	std::cin.getline(dummy, 1024);
}

/* Извежда атлет на екрана */
void displayAthlete(Athlete const &athlete, bool fullName = true)
{
	if( true == fullName ) {
		std::cout << athlete.name << ", ";
	}
	else {
		char family[41];
		std::cout << getAthleteFamily(athlete, family) << ", ";
	}

	std::cout << athlete.team << ", "
			  << athlete.discipline << ", "
			  << athlete.place << std::endl;
}

/* Намира фамилията на атлет, която се връща в параметъра family */
const char * getAthleteFamily(Athlete const &athlete, const char *family)
{
	return getLastWord(athlete.name, family);
}


/* Инициализира списъка с атлети */
void initAthletes(AthleteList &list)
{
	list.count = 0;
}

/* Добавя атлет към списъка с атлети */
void addAthleteToList(AthleteList &list, Athlete const &athlete)
{
	list.athletes[list.count++] = athlete;
}

/* Въвежда атлети в списъка */
void inputAthletes(AthleteList &list)
{
	int athletesCnt;
	// Въвежда и контролира бороя на състезателите
	do {
		std::cout << "Input number of players: ";
		std::cin >> athletesCnt;
		if( athletesCnt>0 && athletesCnt<=100 ) break;

		std::cout << "Number of numer must be in range [1, 100]" << std::endl;
	}
	while(true);

	char dummy[1024];
	cin.getline(dummy, 1024);

	Athlete tmpAthlete;
	for(int i=0; i<athletesCnt;i++) {
		std::cout << "Danni za sastezatel " << (i+1) << ": " << std::endl;
		inputAthlete(tmpAthlete);
		addAthleteToList(list, tmpAthlete);
		std::cout << std::endl;
	}
}

/* Сортира списъка с атлети по тим (и резултат) */
void sortAthletesByTeamAndResult(AthleteList &list)
{
    Athlete tmpAthlete;
    int pos, cmpTeams;
    for(int i=0; i<list.count-1; i++) {
        pos = i;
        for(int j=i+1; j<list.count; j++) {
         	cmpTeams = strcmp(list.athletes[j].team, list.athletes[pos].team);
           	if( cmpTeams < 0 ){
            	pos = j;
           	}
           	else if( 0 == cmpTeams && list.athletes[j].place < list.athletes[pos].place ) {
           		pos = j;
           	}
        }

        if( pos != i ) {
            tmpAthlete = list.athletes[i];
            list.athletes[i] = list.athletes[pos];
            list.athletes[pos] = tmpAthlete;
        }
    }
}

/* Сортира списъка с атлети по име на атлет */
void sortAthletesByName(AthleteList &list)
{
	if(0==list.count) return;

    Athlete tmpAthlete;
    int pos;
    char minLastName[41], lastName[41];
    getAthleteFamily(list.athletes[0], lastName);
    strcpy(minLastName, lastName);

    for(int i=0; i<list.count-1; i++) {
        pos = i;
        for(int j=i+1; j<list.count; j++) {

        	getAthleteFamily(list.athletes[j], lastName);
           	if( strcmp(lastName, minLastName) < 0 ){
            	pos = j;
            	strcpy(minLastName, lastName);
           	}
        }

        if( pos != i ) {
            tmpAthlete = list.athletes[i];
            list.athletes[i] = list.athletes[pos];
            list.athletes[pos] = tmpAthlete;
        }
    }
}

/* Извежда списъка с атлети на екрана */
void displayAthletes(AthleteList const &list, bool fullName = true)
{
	if(0 == list.count) {
		std::cout << "Niama vavaedeni atleti! " << std::endl;
		return;
	}

	for(int i=0; i<list.count; i++) {
		displayAthlete(list.athletes[i], fullName);
		std::cout << std::endl;
	}
}

/* Извежда имената на жените родени след дадена година */
void displayFemaleAthletes(AthleteList const &list, const char *afterDate)
{
	if(0 == list.count) {
		std::cout << "Niama vavaedeni atleti! " << std::endl;
		return;
	}

	std::cout << "Female athletes: " << "\n\n";

	unsigned int foundCnt=0;
	for(int i=0; i<list.count; i++) {
		if( isFemale(list.athletes[i].egn) && checkBirdDate(list.athletes[i].egn, afterDate) ) {
			std::cout << list.athletes[i].name << std::endl;
			foundCnt++;
		}
	}

	if( 0 == foundCnt ) {
		std::cout << "Niama jeni rodeni sled 20.08.1988! " << std::endl;
	}
}

/* Връща списък с атлети, които са медалисти */
AthleteList getMedalistsAthletes(AthleteList const &list)
{
	AthleteList medalists;
	initAthletes(medalists); // важно е да се инициализира

	for(int i=0; i<list.count; i++)
		if( list.athletes[i].place <= 3 )
			addAthleteToList(medalists, list.athletes[i]);

	return medalists;
}

Written by Stoyanoff

24/09/2012 в 17:16

Вашият коментар

Попълнете полетата по-долу или кликнете върху икона, за да влезете:

WordPress.com лого

В момента коментирате, използвайки вашия профил WordPress.com. Излизане /  Промяна )

Google photo

В момента коментирате, използвайки вашия профил Google. Излизане /  Промяна )

Twitter picture

В момента коментирате, използвайки вашия профил Twitter. Излизане /  Промяна )

Facebook photo

В момента коментирате, използвайки вашия профил Facebook. Излизане /  Промяна )

Connecting to %s

%d блогъра харесват това: