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

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

Изпит по информатика в ПУ, 1 юни 2010 г., вариант 1

leave a comment »

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

Условие:

Да се състави компютърна програма за обслужване на фирма за отдаване на коли
под наем, която разполага с до 200 автомобила:

  1. За всяка кола да се въведе следната информация: марка (знаков низ до 40 знака), цвят (знаков низ до 20 знака), наемна цена на ден (число с до 2 цифри в дробната част) и 8 цифрен код на наета кола. Първата цифра от него е код на страна вносител: (1 – Франция, 2 – Италия, 3 – Австрия, 4 – Германия, 5 – Испания, 6 – Англия). Втората цифра е код на класа кола: (1 – малка, 2 – компактна, 3 – средна, 4 –
    ван, 5 – джип). Втората двойка цифри от кода обозначават деня, третата – месеца, а четвъртата – годината, от датата, до която колата е наета. Например код 45120709 означава, че колата е внос от Германия, джип, с дата за връщане 12 юли 2009 г.
  2. Да се изведе списък на всички коли, съдържащ марка, клас, цвят, наемна цена на ден и дата за връщане. Списъкът да бъде подреден по марка (в азбучен ред). Полетата да бъдат разделени със запетая и един интервал. Например:
    Фолксваген Туарег, джип, сребрист, 56.30, 12.07.09.
  3. Да се изведе списък на всички коли (марка, клас, цвят и наемна цена на ден), съдържащи в името си БМВ или Ауди, които не са върнати на дата 14.08.2008 г. Списъкът да бъде подреден по азбучен ред на класа, а тези от един и същи клас – по дата на връщане (в нарастващ ред).
  4. Да се въведе информация за три фирми за отдаване на коли под наем, като се контролира броят на колите да не надхвърля 200. За всяка от тях да се изведат справките от точки 2 и 3 и се пресметне и изведе на екрана средната наемна цена на всички джипове. Да се намери и отпечата най-малката от трите средни цени.

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

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

using namespace std;

// Константи за формата да датата
const short unsigned int YMD_FORMAT = 1; // yy.mm.dd
const short unsigned int DMY_FORMAT = 2; // dd.mm.yy


// Константи с кодове класа автомобил
const short unsigned int KLAS_SMAL    = 1;
const short unsigned int KLAS_COMPACT = 2;
const short unsigned int KLAS_MIDDLE  = 3;
const short unsigned int KLAS_WAN     = 4;
const short unsigned int KLAS_JEEP    = 5;

// Константи указващи кода на функцията за сравнения
const short unsigned int CMP_BY_MARK = 1;
const short unsigned int CMP_BY_KLAS_AND_DATE = 2;

// Помощни функции
/* Намира класа автомобил по зададен код
   Връща указател към низа klasName
 */
char *getKlasName(char *code, char *klasName);
/* Намира годината на внос по зададен код
   Връща указател към низа year
 */
char *getDateByCode(char *code, char *date, unsigned short int format);


// Структура описваща автомобил от автопарка
struct Mobile {
	// Марка на колата
	char mark[41];
	// Цвят на колата
	char color[21];
	// Цена за наемане
	double price;
	// Код на колата
	char code[9];
};

/* Въвежда автомобил */
void inputMobile(Mobile & mobile);
/* Извежда автомобил на екрана */
void displayMobile(Mobile mobile);
/* Проверява дали дадения автомобил съдържа в името си BMW или AUDI и
   дали и НЕ е върнат на 14.08.2008 */
bool checkMobile(Mobile mobile);


// Структура описваща автомобилите в автопарка
struct MobilesList {
	int count;
	Mobile mobiles[200];
};

/* Инициализира списъкът с автомобили */
void initMobilesList(MobilesList & list);
/* Добавя автомобил към списъка */
void addMobileToMobilesList(MobilesList & list, Mobile mobile);
/* Въвежда списък с автомобили */
void inputMobilesList(MobilesList & list);
/* Извежда списъкът с автомобили на екрана */
void displayMobilesList(MobilesList const & list);
/* Връща подсписък по зададените критерии от т. 3 */
MobilesList getMobilesSublist(MobilesList const & list);
/* Връща средната наемна цена на всички джипове */
double getAverageMobilesPrice(MobilesList const & list, int klasType);
/* Сортира списъка, като указва коя функция за сравнение да се извика.
   (По принцип се реализира чрез указател към тип функция)
*/
void sortMobilesList(MobilesList & list, int cmpFunc);
/* Сравнява два автомобила по марка (лексикографски) */
int cmp_by_mark(Mobile mobile1, Mobile mobile2);
/* Сравнява два автомобила по клас и по дата  */
int cmp_by_klas_and_date(Mobile mobile1, Mobile mobile2);



int main()
{
	MobilesList mobilesList, subMobilesList;
	double minAveragePrice;

	// Въвеждат се и се обработват 3 автосалона
	for( int i=1; i<=3; i++) {

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


		// Инициализира празен списък от автосалон
		initMobilesList(mobilesList);

		// Въвежда се списъкът от автосалона
		std::cout << "[ Input mobiles ] \n\n";
		inputMobilesList(mobilesList);

		// Извежда се списъкът от автосалона сортиран по марка
		std::cout << "[ List of mobiles ] \n\n";
		sortMobilesList(mobilesList, CMP_BY_MARK);
		displayMobilesList(mobilesList);

		// Намира списък с автомобилите от точка 3
		std::cout << "[ List BMW and Audi mobiles to return at  14.08.2008 ] \n\n";
		subMobilesList = getMobilesSublist(mobilesList);
		sortMobilesList(subMobilesList, CMP_BY_KLAS_AND_DATE);
		if( subMobilesList.count > 0) {
			displayMobilesList(subMobilesList);
		}
		else {
			std::cout << "Not found mobiles!\n";
		}

		double avgPrice;
		avgPrice = getAverageMobilesPrice(mobilesList, KLAS_JEEP);
		std::cout << "[ Average price of jeeps ]" << avgPrice << std::endl;

		if( 1 == i ){
			minAveragePrice = avgPrice;
		}
		else if(avgPrice < minAveragePrice){
			minAveragePrice = avgPrice;
		}

		std::cout << std::endl;
	}

	cout << "Min jeep average price: " << minAveragePrice << std::endl;

	return 0;
}



/* Намира класа автомобил по зададен код
   Връща указател към низа klasName
 */
char *getKlasName(char *code, char *klasName)
{
	unsigned short int klasCode;
	klasCode = code[1]-'0';

	switch(klasCode) {
		case KLAS_SMAL    :
			strcpy(klasName, "malak"); break;
		case KLAS_COMPACT :
			strcpy(klasName, "kompakten"); break;
		case KLAS_MIDDLE  :
			strcpy(klasName, "sreden"); break;
		case KLAS_WAN     :
			strcpy(klasName, "van"); break;
		case KLAS_JEEP    :
			strcpy(klasName, "jeep"); break;
	}

	return klasName;
}

/* Намира годината на внос по зададен код
   Връща указател към низа year
 */
char *getDateByCode(char *code, char *date, unsigned short int format=DMY_FORMAT)
{
	unsigned short int positions[3] = {2,4,6};
	if( YMD_FORMAT==format ){
		positions[0] = 6;
		positions[1] = 4;
		positions[2] = 2;
	}

	char *p=(char *)date;
	unsigned short int pos;
	for(int i=0; i<3; i++){
		pos = positions[i];
		*p++=code[pos];
		*p++=code[pos+1];
		*p++='.';
	}
	*p='\0';

	return date;
}



/* Въвежда автомобил */
void inputMobile(Mobile & mobile)
{
	std::cout << "Mark: ";
	std::cin.getline(mobile.mark, 41);

	std::cout << "Color: ";
	std::cin.getline(mobile.color, 21);

	std::cout << "Price: ";
	std::cin >> mobile.price;

	std::cout << "Code: ";
	std::cin >> mobile.code;
	cin.get();
}

/* Извежда автомобил на екрана */
void displayMobile(Mobile mobile)
{
	char buff[256];
	std::cout << mobile.mark << ", ";
	std::cout << getKlasName(mobile.code, buff) << ", ";
	std::cout << mobile.color << ", ";
	std::cout << mobile.price << ", ";
	std::cout << getDateByCode(mobile.code, buff) << std::endl;
}

/* Проверява дали дадения автомобил съдържа в името си BMW или AUDI и
   дали и НЕ е върнат на 14.08.2008 */
bool checkMobile(Mobile mobile)
{
	// Ако не съдържа нито Audi нито BMW  в името си се връща false
	if( NULL==strstr(mobile.mark, "Audi") && NULL==strstr(mobile.mark, "BMW") ) {
		return false;
	}

	char date[20];
	getDateByCode(mobile.code, date, DMY_FORMAT);
	if( 0 != strcmp(date, "14.08.2008") ) {
		return false;
	}

	return true;
}



/* Инициализира списъкът с автомобили */
void initMobilesList(MobilesList & list)
{
	list.count = 0;
}

/* Добавя автомобил към списъка */
void addMobileToMobilesList(MobilesList & list, Mobile mobile)
{
	list.mobiles[list.count++] =  mobile;
}

/* Въвежда списък с автомобили */
void inputMobilesList(MobilesList & mobiles)
{
	int cntMobiles;
	do {
		std::cout << "Input mobiles count: ";
		std::cin >> cntMobiles;

		if(cntMobiles> 0 && cntMobiles<=200 ) break;

		std::cout << "Count must be in interval [1, 200]! " << std::endl;
	}
	while(true);
	std::cin.get();

	Mobile mobile;
	for(int i=0; i<cntMobiles; i++){
		std::cout << "Input mobile " << (i+1) << ":\n\n";
		inputMobile(mobile);
		addMobileToMobilesList(mobiles, mobile);
		std::cout << std::endl;
	}
}

/* Извежда списъкът с автомобили на екрана */
void displayMobilesList(MobilesList const & list)
{
	for(int i=0; i<list.count; i++) {
		displayMobile(list.mobiles[i]);
	}
	std::cout << std::endl;
}

/* Връща подсписък по зададените критерии от т. 3 */
MobilesList getMobilesSublist(MobilesList const & list)
{
	MobilesList foundMobiles;
	initMobilesList(foundMobiles);

	for(int i=0; i<list.count; i++){
		if( true == checkMobile(list.mobiles[i]) ){
			addMobileToMobilesList(foundMobiles, list.mobiles[i]);
		}
	}

	return foundMobiles;
}

/* Връща средната наемна цена на всички автомобили от даден клас (джипове) */
double getAverageMobilesPrice(MobilesList const & list, int klasType=KLAS_JEEP)
{
	double totalPrice=0.0;
	int klas, cnt=0;
	for(int i=0; i<list.count; i++){
		klas = list.mobiles[i].code[1]-'0';
		if( klasType == klas ){
			totalPrice+=list.mobiles[i].price;
			cnt++;
		}
	}

	if(0 == cnt) return 0.0;

	return totalPrice/cnt;
}

/* Сортира списъка, като указва коя функция за сравнение да се извика.
   (По принцип се реализира чрез указател към тип функция)
*/
void sortMobilesList(MobilesList & list, int cmpFunc=CMP_BY_MARK)
{
    Mobile tmpMobile;
    int pos, cmp;
    for(int i=0; i<list.count-1; i++) {
        pos = i;
        for(int j=i+1; j<list.count; j++) {

        	switch(cmpFunc){
        		case CMP_BY_MARK :
        			cmp = cmp_by_mark(list.mobiles[j], list.mobiles[pos]);
        			break;
        		case CMP_BY_KLAS_AND_DATE :
        			cmp = cmp_by_klas_and_date(list.mobiles[j], list.mobiles[pos]);
        			break;
        		default :
        			cmp=0;
        	}

           	if( cmp < 0 ){ 	pos = j; }
        }

        if( pos != i ) {
            tmpMobile = list.mobiles[i];
            list.mobiles[i] = list.mobiles[pos];
            list.mobiles[pos] = tmpMobile;
        }
    }
}

/* Сравнява два автомобила по марка (лексикографски) */
int cmp_by_mark(Mobile mobile1, Mobile mobile2)
{
	return strcmp(mobile1.mark, mobile2.mark);
}

/* Сравнява два автомобила по клас и по дата  */
int cmp_by_klas_and_date(Mobile mobile1, Mobile mobile2)
{
	char date1[20], date2[20], tmp1[20], tmp2[20];
	getDateByCode(mobile1.code, tmp1, YMD_FORMAT); // Връща yy.mm.dd
	getDateByCode(mobile2.code, tmp2, YMD_FORMAT); // Връща yy.mm.dd

	// Преобразува от yy.mm.dd до yyyy.mm.dd
	if( tmp1[0] <= '1' ) strcpy(date1, "20");
	else strcpy(date1, "19");

	if( tmp2[0] <= '1' ) strcpy(date2, "20");
	else strcpy(date2, "19");

	strcat(date1, tmp1);
	strcat(date2, tmp2);

	if( '0' == date1[0] ) {
		if( '0' == date2[0] ) return strcmp(date1, date2);
		else return 1;
	}
	else {
		if( '0' == date2[0] ) return -1;
		else return strcmp(date1, date2);
	}
}

Written by Stoyanoff

18/10/2012 в 10:35

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

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

WordPress.com лого

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

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s

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