---
# System prepended metadata

title: Przydatne informacje z OBOZU C++

---

# Przydatne informacje z OBOZU C++
Największy Wspólny Dzielnik (NWD)

Dla zadanych liczb a,b
chcemy znaleźć najwiekszą liczbę c taką, że dzieli ona zarówno a jak i b

. Na przykład NWD(18, 24) = 6 oraz NWD(6, 8) = 2.

## Obserwacja 1
Łatwo zauważyć, że każda liczba dzieli 0
, więc dla każdego a zachodzi **NWD(a,0)=a**



 

## Twierdzenie 1
Jeśli c
jest największym wspólnym dzielnikiem a,b oraz a≤b, to c jest też największym wspólnym dzielnikiem a−b,b.
Zapisane inaczej:
**NWD(a,b)=NWD(a−b,b)**

 

## Obserwacja 2
Weźmy a=23
oraz b=4. Wtedy z poprzedniego twierdzenia:
NWD(23,4)=NWD(19,4)=NWD(15,4)=NWD(11,4)=NWD(7,4)=NWD(3,4)
Zauważmy, że to samo możemy osiągnąć w jednej operacji zamiast odejmowania robiąc modulo, bo 23%4=3

 

## Twierdzenie 2
**NWD(a,b)=NWD(a%b,b)**

Algorytm (Euklidesa)
Mamy dwie zmienne a,b
. Zamieniamy je miejscami tak, aby w a była większa liczba, a w b mniejsza. Potem w pętli dopóki obie są różne od 0 robimy a=a%b, a następnie (skoro nasze nowe a jest mniejsze od b) zamieniami te zmienne miejscami. Kiedy jedna z tych zmiennych jest równa 0

, przerywamy pętlę i wypisujemy drugą liczbę jako NWD.

 

## NWW
Mając NWD umiemy obliczyć Najwiekszą Wspólną Wielokrotność (NWW) dwóch liczb ze wzoru:
**NWW(a,b)=(a⋅b)/NWD(a,b)**

# Zmienne znakowe i napisy
## Zmienne typu char(acter)

W C++ mamy do dyspozycji typ dla zmiennych znakowych. W zmiennych tych mogą być trzymane wartości z zakresu [−128,127]

. Funkcje wyjścia/wejścia interpretują odpowiednio typ znakowy, wypisując zamiast znajdującej się w zmiennej liczbę, odpowiadający tej liczbie znak z tabeli ASCII.
## Znak a liczba

Skoro wiemy, że znaki to tak naprawdę liczby, nie musimy pamiętać wartości tablicy ASCII. W kodzie znak traktowany jest po prostu jak liczba typu char.
Przykład:

'!' + '$' == 33 + 36 == 69 == 'E'

Sprawdzanie wielkości litery
```cpp=
char c;
cin>>c;

if(c >= 'a' && c <= 'z')
    cout<<"mala litera\n";
else if (c >= 'A' && c <= 'Z')
    cout<<"wielka litera\n";
else
    cout<<"nie litera\n";
    ```

Zamiana wielkiej litery na małą

```cpp=char c;
cin>>c; //zakładamy tu, że c to znak o wartości pomiędzy [65, 90]

c = c + 32;
cout<<c<<'\n';
```
Zamiana cyfry na liczbę
```cpp=
char c;
cin>>c; //zakładamy tu, że c to znak o wartości pomiędzy [48, 57]

int a = c - '0';
```

# Tablice dwuwymiarowe

int tab[n][m] oznacza, że deklarujemy tablicę wielkości nxm, gdzie n interpretujemy jako liczba wierszy, a m jako liczba kolumn.

Poniżej znajduje się przykładowy kod do tablic dwuwymiarowych:
```cpp=
#include <iostream>
using namespace std;
int tab[100][100];
int wie = 100, kol=100;
int main(){
    int licznik=0;
    for(int w=0; w<wie; w++){
      for(int k=0; k<kol; k++){
        tab[w][k]=licznik;
        licznik++;
      }
    }
    for(int w=0; w<wie; w++){
        for(int k=0; k<kol; k++){
          cout<<tab[w][k]<<" ";
      
        }
        cout<<"\n";
    }
}
```
## O macierzach:

    Macierz to tablica dwuwymiarowa.
    Macierze można dodawać, odejmować i mnożyć przez liczbę.

## Wskazówki do kodu:

Lepiej pisać zmienne w taki sposób, żeby od razu było wiadomo, co oznaczają:
```cpp=
int wiersze;// liczba wierszy
int kolumny; // liczba kolumn
```
albo
```cpp=
int wie; //liczba wierszy
int kol; //liczba kolumn
```
Jeśli zadanie nie wymaga innego sposobu - najlepiej jest iterować się najpierw po wierszach a potem po kolumnach:
```cpp=
    for(int w=0; w<wie; w++){
        for(int k=0; k<kol; k++){
          //wasz kod
        }
    }
```

# Tablice jednowymiarowe

## Tablice domyślnie deklarujemy w przestrzeni globalnej.

Przykłady:
```cpp=
#include <iostream>
using namespace std;
// (przestrzeń globalna)

// np. dla n <= 10^6
int tab[1000006]; // <- zawsze deklarujemy trochę więcej niż potrzebujemy
// ↑ tablice tworzone w przestrzeni globalnej są wyzerowane.

// ciekawostka, że tak można
const int P = 1e6+6;
int tab2[P];

// za pomocą nawiasów klamrowych,
// można przypisywać wartości do tablicy przy jej tworzeniu.
int test[3]={1,2,3}; 

int main(){
    int c; // <- UWAGA! Zmienna bez zainicjalizowanej wartości
    int tab3[100]={}; // <- tak też stworzymy wyzerowaną tablicę
    // jednkaże zwykle nie deklarujemy dużych tablic w funkcjach,
    // a w przestrzeni globalnej
    
    // ❌ TAK NIE ROBIMY:
    tab3[100] = 3;   // <- tab3 ma zakres od 0 do 99
    cout<<tab3[105]; // <----------------------------
    
    tab = 7; // tab to wskaźnik na tablicę, a nie zmienna!
    cout<<tab; //<- to nie wypisze nam całej tablicy :(
    
    int n;
    cin>>n;
    int tab4[n]; // NIE WOLNO TAK ROBIĆ! W języku C jest to nielegalne.
    
...
```
# Warto wiedzieć!

    Typ int ma 4 bajty = 32 bity.
    W zmiennej typu int możemy trzymać liczby od −231

(~ -2mld.) do 231−1

    (~ 2 mld.)
    Trzeba pamiętać, że gdy nie przypisujemy wartości danej komórce pamięci, to znajduje się tam losowa wartość (tak jak znak zapytania w maszynie RAM).
    Zadania na Themisie i na konkursach często mają limit pamięci. Jednym z przeliczników, które warto znać jest ten, że tablica miliona intów ma rozmiar 4MB.
    Deklarując tablicę musimy pamiętać o jej odpowiedniej wielkości. Nie możemy jako programiści dopuścić do zaglądania w “nie naszą pamięć”. Np. próba odczytu lub zapisu do komórki spoza tablicy, w zadaniu na Themisie, np. tab[-1], lub tab[10] (dla tablicy 10 elementowej), zakończy się odpowiednim błędem.
    Próba zapisu liczby o typie innym niż zmienna do której zapisujemy, nie zakończy się błędem. Program wykona swoje zadanie, odpowiednio ucinając liczbę, lub modyfikując ją w inny sposób.
    Np. cout<<(int)(3.5); wypisze liczbę 3.
    By przyspieszyć działanie programu poprzez wyłączenie synchronizacji strumieni (i innych niepotrzebnych nam elementów) dodajemy na początku funkcji main linijki:
```cpp=
ios_base::sync_with_stdio(false);
cin.tie(0);
```
