PROGRAMOWANIE I ALGORYTMY

Matura 2015 - nowa formuła, zadanie 4


powrót

Rozwiązanie zadania 4 - matura 2015 - nowa formuła

Treść zadania:

W pliku liczby.txt znajduje się 1000 liczb naturalnych zapisanych binarnie. Każda liczba zapisana jest w osobnym wierszu. Pierwsze pięć wierszy zawiera następujące liczby:

  • 11010100111
  • 11110111111011101
  • 1010100111010100
  • 1101111111111111111111010100101010101001
  • 1010110011001101010011110101010101010111

 

Każda liczba binarna zawiera co najwyżej 250 cyfr binarnych, co oznacza, że w wielu językach programowania wartości niektórych z tych liczb nie da się zapamiętać w pojedynczej zmiennej typu całkowitoliczbowego, np. w języku C++ w zmiennej typu int. Napisz program, który da odpowiedzi do poniższych zadań. Odpowiedzi zapisz w pliku wynik4.txt, a każdą odpowiedź poprzedź numerem oznaczającym odpowiednie zadanie.

Zadanie 4.1. (0–3) Podaj, ile liczb z pliku liczby.txt ma w swoim zapisie binarnym więcej zer niż jedynek. Przykład: Dla zestawu liczb:

  • 101011010011001100111
  • 10001001
  • 1000000
  • 101010011100
  • 100010

wynikiem jest liczba 3 (3 podkreślone liczby mają w swoim zapisie więcej zer niż jedynek).

Rozwiązanie

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

//funkcja sprawdza, czy liczba ma wiecej zer
bool czy_wiecej(string liczba)
{
	int licz = 0;
	for(int i = 0; i < liczba.size(); i++)
		if(liczba[i]=='0') ++licz;
		else	--licz;
	
	//jesli wiecej jest 0
	if(licz > 0) return true;
	
	return false;
}

int main()
{
	ifstream in("liczby.txt");
	
	if(in.is_open())
	{
		string liczba; //wczytana liczba
		int ile = 0; 
		
		for(int i=0; i<1000; i++)
		{
			in>>liczba;
			if(czy_wiecej(liczba)) ++ile;	
		}
		
		cout<<"Takich liczb jest: "<<ile<<endl;;
		in.close();
	}
	else
		cout<<"Problem z otwarciem pliku \"liczby.txt\"";
		
	return 0;
}

Zadanie 4.2. (0–3) Podaj, ile liczb w pliku liczby.txt jest podzielnych przez 2 oraz ile liczb jest podzielnych przez 8. Przykład: Dla zestawu liczb:

  • 101011010011001100000 (*), (**)
  • 10001001 100100 (*)
  • 101010010101011011000 (*), (**)
  • 100011

trzy liczby są podzielne przez 2 (*) i dwie liczby są podzielne przez 8 (**).

Rozwiązanie

Liczba w zapisie binarnym dzieli się przez dwa, jeśli na końcu stoi co najmniej jedno 0, natomiast przez osiem gdy tych zer jest co najmniej trzy.

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

bool czy_przez_dwa(string liczba)
{
	//sprawdzenie, czy ostatni znak jest 0
	if(liczba[liczba.size()-1]=='0') 
		return true;
	return false;
}

bool czy_przez_osiem(string liczba)
{
	//sprawdzenie, czy trzy ostatnie znaki to 0
	if(liczba[liczba.size()-1]=='0'&&
	liczba[liczba.size()-2]=='0'&&
	liczba[liczba.size()-3]=='0') 
		return true;
	//gwarantuje sie, ze sa co najmniej trzy znaki
	return false;
}
int main()
{
	ifstream in("liczby.txt");
	
	if(in.is_open())
	{
		string liczba; //wczytana liczba
		int przez_dwa = 0, przez_osiem = 0; 
		
		for(int i=0; i<1000; i++)
		{
			in>>liczba;
			if(czy_przez_dwa(liczba)) ++przez_dwa;
			if(czy_przez_osiem(liczba)) ++przez_osiem;	
		}
		
		cout<<"Liczb podzielnych przez 2 jest: "<<przez_dwa<<endl;
		cout<<"Liczb podzielnych przez 8 jest: "<<przez_osiem<<endl;
		in.close();
	}
	else
		cout<<"Problem z otwarciem pliku \"liczby.txt\"";
		
	return 0;
}

Zadanie 4.3. (0–6) Znajdź najmniejszą i największą liczbę w pliku liczby.txt.

Jako odpowiedź podaj numery wierszy, w których się one znajdują. Przykład: Dla zestawu liczb:

  • 101011010011001100111
  • 10001001011101010
  • 1001000
  • 101010011100
  • 1000110

najmniejsza liczba to: 1000110 największa liczba to: 101011010011001100111 Prawidłowa odpowiedź dla powyższego przykładu to: 5, 1.

Rozwiązanie

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
	ifstream in("liczby.txt");
	
	if(in.is_open())
	{
		//liczba - wczytana liczba z pliku
		//pomMin - przechowuje najmniejsza liczbe
		//pomMax - przechowuje najwieksza liczbe
		string liczba, pomMin, pomMax;
		
		//i - zlicza wiersze, nrMin - wiersz z najmniejsza liczba
		//nrMax - wiersz z najwieksza liczba
		int nrMin = 1, nrMax = 1;
		
		in>>liczba; //wczytanie pierwszej liczby
		
		pomMin = pomMax = liczba;
		
		for(int i=2; i<1001; i++)
		{
			in>>liczba;
			//szukanie maksymalnej --------------------------------------
			//jesli wczytana liczba ma wiecej znaków
			//oznacza to, ze jest wieksza
			if(liczba.size() > pomMax.size())
			{
				pomMax = liczba; //zapamietaj ja
				nrMax = i; //zapamietaj wiersz
			} 
			else
				//jesli maja po tyle samo znaków
				//to trzeba sprawdzic, która jest wieksza
				//operator > porównuje leksykograficznie
				if(liczba.size()==pomMax.size())
					if(liczba > pomMax)
					{
						//zapamietujemy ja
						pomMax = liczba;
						//oraz jej pozycje
						nrMax = i;
					}
			//szukanie minimalnej --------------------------------------
			//jesli wczytana liczba ma mniej znaków
			//oznacza to, ze jest mniejsza
			//operator < porównuje leksykograficznie
			if(liczba.size() < pomMin.size())
			{
				pomMin = liczba; //zapamietaj ja
				nrMin = i; //zapamietaj wiersz
			} 
			else
				//jesli maja po tyle samo znaków
				//to trzeba sprawdzic, która jest mniejsza
				if(liczba.size()==pomMin.size())
					if(liczba < pomMin)
					{
						//zapamietujemy ja
						pomMin = liczba;
						//oraz jej pozycje
						nrMin = i; 
					}	
		}
		
		cout<<"Najmniejsza znajduje sie we wierszu: "<<nrMin<<endl;
		cout<<"Najwieksza znajduje sie we wierszu: "<<nrMax<<endl;
		in.close();
	}
	else
		cout<<"Problem z otwarciem pliku \"liczby.txt\"";
	
	return 0;
}