Zadanie

Izby na internátoch nie sú veľmi zaujímavé. Všetky vyzerajú rovnako – na jednej stene sú skrine, na druhej okno a balkón, zvyšné dve sú skoro prázdne. Niektorí študenti si na to jednoducho zvyknú a často chodia domov, tí ostatní sa snažia svoje izby trochu zútulniť.

Baška a Olívia sa o to snažili tiež. Doniesli si farebné obliečky na paplóny, kúpili si koberec, oblepili ošarpané poličky pekným papierom a dokonca aj vymaľovali. Keď už boli takmer spokojné, všimli si veľkú prázdnu plochu na stene nad poličkou. Hneď im bolo jasné, že tam treba niečo zavesiť. Zhodli sa, že to bude obraz a že by mal byť veľký, aby zakryl čo najviac z ich steny. Vedeli, akú plochu má ich stena, stačilo už len nájsť k nej dostatočne vhodný obraz.

Vybrali sa preto do obchodu. Obchod bol veľký a bolo v ňom veľa stien a veľa obrazov. Nevedeli sa na žiadnom zhodnúť, tak si ich všetky nafotili, aby si ich mohli v pokoji na izbe pozrieť a vybrať ten najvhodnejší.

Úloha

Na vstupe dostanete jednu fotku v podobe ASCII art. Vašou úlohou je nájsť na fotografii obraz a zistiť, aký je veľký. Obraz sa skladá z ľubovolných znakov a medzier. Je celý ohraničený obdĺžnikovým rámom. Zvyšok vstupu tvoria medzery a znázorňujú stenu okolo obrazu na fotografii. Veľkosť obrazu je plocha steny, ktorú zakryje, teda jeho výška krát šírka v ASCII znakoch (každý obraz je obdĺžnikový).

Formát vstupu

Na vstupe je niekoľko rovnako dlhých riadkov ukončených znakom konca riadku. Dĺžka jedného riadku neprekročí 250 znakov. Rám sa skladá zo znakov + v rohoch, - navrchu a dole a znaku | na bokoch. Každý obraz má veľkosť minimálne 1 (do tejto hodnoty sa neráta plocha rámu).

Formát výstupu

Vypíšte jedno číslo – veľkosť plochy obrazu bez rámu. Nezabudnite za výsledkom vypísať koniec riadku.

Príklad

Input:

                                    
                                    
                                    
                                    
   +---------------------------+    
   |   .-. .-. .----..----.    |    
   |   | |/ / { {__  | {}  }   |    
   |   | |\ \ .-._} }| .--'    |    
   |   `-' `-'`----' `-'       |    
   +---------------------------+    
                                    
                                    
                                    
                                    
                                    

Output:

108

Obraz má šírku \(27\) znakov a výšku \(4\) znaky, t.j. veľkosť \(27\times 4=108\). Na začiatku sú \(4\) riadky plné medzier, pred obrazom sú na každom riadku \(3\) medzery a za ním \(4\), na konci je ešte \(5\) riadkov plných medzier. (Vstup z pdf zadania sa vám možno neskopíruje v správnom formáte)

Ako funguje čítanie vstupu? Štandardne čítame vstup po slovách – funkcie ako cin a read nám do premennej uložia ďalšie slovo (alebo číslo) na vstupe.

Každý textový súbor (aj vstup pre naše programy) sa skladá z množstva znakov. Niektoré z nich sú takzvané prázdne znaky (whitespace characters) – napríklad medzera (' '), tabulátor ('\t'), znak nového riadku ('\n') alebo aj znak konca súboru (EOF, End Of File). Program tieto prázdne znaky pri čítaní vstupu pomocou horeuvedených funkcií preskakuje. Na to, aby sme vyriešili túto úlohu, musíme postupovať inak…

Vstup musíme čítať buď po jednotlivých znakoch, kedy načítame naozaj každý znak na vstupe samostatne, alebo načítavať celé riadky naraz – teda načítať znaky, až kým neprídeme k znaku konca riadku.

Ako to ale naprogramovať? Ak ste nič takéto ešte nerobili, na internete rýchlo nájdete odpoveď.

Čítanie celých riadkov je pre nás o niečo pohodlnejšie. V C++ na to môžeme použiť funkciu getline(cin, s), kde s je názov premennej typu string. Táto funkcia vracia hodnotu typu boolean, ktorá je true, ak sa programu podarilo niečo načítať. Ak používame Pascal, môžeme použiť funkciu readln(s). Ak by ste potrebovali zistiť, čo presne dané funkcie robia, ľahko nájdete ich presné popisy na internete v dokumentácií daných jazykov, napríklad pre C++ na stránke cplusplus.com.

Keď už vieme vstup načítať, musíme ešte vymyslieť, ako spočítať plochu obrazu. Jedna možnosť je pozerať sa na výskyt znakov +, ktoré tvoria rám obrazu. Musíme si však dať pozor, aby nás nepomýlil znak + vo vnútri obrazu. Najelegantnejšie to vyriešime tak, že si uložíme súradnice prvého a posledného + na vstupe a z nich následne vypočítame plochu obrazu.

#include <iostream>

using namespace std;

int main()
{
    string s;
    bool prvy = false;
    int sx, sy, fx, fy, riadok = 0;
    while(getline(cin, s))
    {
        for(int stlpec = 0; stlpec < s.size(); stlpec++)
        {
            if(s[stlpec] == '+')
            {
                if(!prvy)
                {
                    prvy = true;
                    sx = stlpec;
                    sy = riadok;
                }
                fx = stlpec;
                fy = riadok;
            }
        }
        riadok++;
    }
    cout << (fx-sx-1)*(fy-sy-1) << endl;
}

Druhou možnosťou je zistiť počet riadkov, ktoré nie sú prázdne, zistiť dĺžku jedného z nich po orezaní medzier na okrajoch a veľkosť dopočítať z týchto dvoch údajov.

#include <iostream>

using namespace std;

string trim(string str)
{
    int first = str.find_first_not_of(' ');
    int last = str.find_last_not_of(' ');
    if(first == -1) return "";
    return str.substr(first, (last-first+1));
}

int main(){
    string s;
    int sirka = 0;
    int vyska = 0;
    while(getline(cin, s)){
        s = trim(s);
        if(s.length() > 0){
            sirka = s.length();
            vyska++;
        }
    }
    cout << (sirka-2)*(vyska-2) << endl;
}
import sys

width, height = 0, 0

for line in sys.stdin:
    if len(line.strip()) > 0:
        height += 1
        width = len(line.strip())

print((width - 2) * (height - 2))

Diskusia

Tu môžte voľne diskutovať o riešení, deliť sa o svoje kusy kódu a podobne.

Pre pridávanie komentárov sa musíš prihlásiť.