eMatematikas Prisijunk Forumas Egzaminų užduotys ONLINE testai

IT VBE 2019 2 užduotis. Sportas. Programavimas C++. Nesigauna atsakymas


Užduoties sąlyga yra 8-9 psl. šiuo adresu: https://www.nec.lt/failai/8018_IT-VBE-1_2019.pdf

Norėčiau, kad kas nors parodytų, kaip reikia išspręsti šią užduotį, kad būtų spausdinamas atsakymas.

Mano neteisingas sprendimas:

#include <iostream>
#include <fstream>

using namespace std;

struct Sportininkai{
string vardas;
int nr;
int val;
int min;
int sek;
int suviai;
};

void Skaityti(int &n, int &m, Sportininkai A[], Sportininkai B[]);
void UztrukesLaikas(int n, int m, int kiekv, int kiekm, Sportininkai A[], Sportininkai B[], Sportininkai C[], Sportininkai D[]);
void Rikiavimas(int m, Sportininkai C[], Sportininkai D[]);
void Spausdinti(int kiekv, int kiekm, Sportininkai C[], Sportininkai D[]);

int main()
{
    int n, m;
    int kiekv, kiekm;

    Sportininkai A[30], B[30], C[30], D[30];

    Skaityti(n, m, A, B);
    UztrukesLaikas(n, m, kiekv, kiekm, A, B, C, D);
    Rikiavimas(m, C, D);
    Spausdinti(kiekv, kiekm, C, D);

    return 0;
}
void Skaityti(int &n, int &m, Sportininkai A[], Sportininkai B[])
{
    ifstream fd("U2.txt");

    char eil[21];
    int s;

    fd >> n;

    for(int i=0; i<n; i++)
    {
        fd.ignore(80, '\n');
        fd.get(eil, sizeof eil);

        A[i].vardas=eil;
        fd >> A[i].nr;
        fd >> A[i].val;
        fd >> A[i].min;
        fd >> A[i].sek;
    }

    fd >> m;
    int kiekm=0;
    int kiekv=0;
    for(int i=0; i<m; i++)
    {
        fd.ignore(80, '\n');

        fd >> B[i].nr;
        fd >> B[i].val;
        fd >> B[i].min;
        fd >> B[i].sek;
        if(B[i].nr/100==2)
        {
            kiekv++;
            B[i].suviai=0;
            for(int i=1; i<=4; i++)
            {
                fd >> s;
                B[i].suviai=B[i].suviai+s;
            }

        }
            if(B[i].nr/100==1)
        {
                kiekm++;
            B[i].suviai=0;
            for(int i=1; i<=2; i++)
            {
                fd >> s;
                B[i].suviai=B[i].suviai+s;
            }
        }
    }
    fd.close();
}
void UztrukesLaikas(int n, int m, int kiekv, int kiekm, Sportininkai A[], Sportininkai B[], Sportininkai C[], Sportininkai D[])
{

    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(B[i].nr==A[j].nr)
            {
                for(int i=0; i<=kiekm; i++)
                {
                    C[i].nr=B[i].nr;
                    C[i].vardas=B[i].vardas;
                  C[i].val=((B[i].val*60*60+B[i].min*60+B[i].sek+(10-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))/60/60;
                  C[i].min=((B[i].val*60*60+B[i].min*60+B[i].sek+(10-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))/60;
                  C[i].sek=((B[i].val*60*60+B[i].min*60+B[i].sek+(10-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))%60;
                }

                for(int i=0; i<=kiekv; i++)
                {
                    D[i].nr=B[i].nr;
                    D[i].vardas=B[i].vardas;
                  D[i].val=((B[i].val*60*60+B[i].min*60+B[i].sek+(20-(B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))/60)/60;
                  D[i].min=((B[i].val*60*60+B[i].min*60+B[i].sek+(20-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))/60;
                  D[i].sek=((B[i].val*60*60+B[i].min*60+B[i].sek+(20-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))%60;
                }

            }
        }
    }
}
void Rikiavimas(int m, Sportininkai C[], Sportininkai D[])
{
    for(int i=0; i<m-1; i++)
    {
        for(int j=i+1; j<m; j++)
        {
            if(C[i].val*60*60+C[i].min*60+C[i].sek>C[j].val*60*60+C[j].min*60+C[j].sek)
                swap(C[i], C[j]);
            else if(C[i].val*60*60+C[i].min*60+C[i].sek==C[j].val*60*60+C[j].min*60+C[j].sek)
            {
                if(C[i].vardas>C[j].vardas)
                    swap(C[i], C[j]);
            }

            if(D[i].val*60*60+D[i].min*60+D[i].sek>D[j].val*60*60+D[j].min*60+D[j].sek)
                swap(D[i], D[j]);
            else if(D[i].val*60*60+D[i].min*60+D[i].sek==D[j].val*60*60+D[j].min*60+D[j].sek)
            {
                if(D[i].vardas>D[j].vardas)
                    swap(D[i], D[j]);
            }
        }
    }
}
void Spausdinti(int kiekv, int kiekm, Sportininkai C[], Sportininkai D[])
{
    ofstream fr("U2rez.txt");

    fr << "Merginos " << endl;
    for(int i=0; i<=kiekm; i++)
        fr << C[i].nr << " " << C[i].vardas << " " << C[i].val << " " << C[i].min << " " << C[i].sek << endl;

    fr << "Vaikinai " << endl;
    for(int i=0; i<=kiekv; i++)
        fr << D[i].nr << " " << D[i].vardas << " " << D[i].val << " " << D[i].min << " " << D[i].sek << endl;

    fr.close();
}

Sprendimas gal ir būtų teisingas, bet dėl gilių ciklų ir pastovaus laiko formato perskaičiavimo kodas tampa neįskaitomu tiek pačiam, tiek kitiems.

Keletas patarimų ateičiai:
* Laiką geriausia iškarto pasiversti į sekundes ir atversti atgal tik tada, kai jau reikės spausdinti - nusiims visa painiava ir bus lengviau struktūruoti bei suprasti kodą. Pvz:         fd >> A[i].nr;
        fd >> A[i].val;
        fd >> A[i].min;
        fd >> A[i].sek;
Pakeisti į
fd >> val;
        fd >> minn;
        fd >> sek;
        A[i].laikas = val*60*60 + minn*60 + sek;
Ir visur kitur toliau dirbti tik su sekundėmis, o spausdinant galutinį rezultatą atversti laiką atgal į valandų/minučių/sekundžių formatącout << C[i].nr << " " << C[i].vardas << " " << C[i].laikas/(60*60) << " " << C[i].laikas/60%60 << " " << C[i].laikas%60 << endl;
* Kadangi užduotis neprašo nei atskiros funkcijos užtrukto laiko skaičiavimui, nei prašo saugoti startinio laiko duomenis, trasos įveikimo laiką galima suskaičiuoti vienu sakiniu vos tik nuskaičius finišo duomenis. Pvz: B[i].laikas = (val*60*60+minn*60+sek) - A[j].laikas;
* Taip pat ir nepataikyti šūviai užduoties požiūriu tėra tik +60 skundžių prie rezultato - nėra prasmės jų saugoti, galima iškarto pridėti prie sportininko laiko. Pvz vaikinų 4 šaudymo rungčių baudų skaičiavimas:            for(int j=0; j<4; j++)
            {
                fd >> s;
                B[i].laikas += 60*(5-s);
            }

* Nenaudoti vienodų kintamųjų vidiniuose cikluose. Pvz, kaip šiame fragmente:
void UztrukesLaikas(int n, int m, int kiekv, int kiekm, Sportininkai A[], Sportininkai B[], Sportininkai C[], Sportininkai D[])
{

    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(B[i].nr==A[j].nr)
            {
                for(int i=0; i<=kiekm; i++)
                {
                    C[i].nr=B[i].nr;
                    C[i].vardas=B[i].vardas;
                  C[i].val=((B[i].val*60*60+B[i].min*60+B[i].sek+(10-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))/60/60;
                  C[i].min=((B[i].val*60*60+B[i].min*60+B[i].sek+(10-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))/60;
                  C[i].sek=((B[i].val*60*60+B[i].min*60+B[i].sek+(10-B[i].suviai)*60)-(A[j].val*60*60+A[j].val*60+A[j].sek))%60;
                }

Šioje vietoje visiškai neaišku kur ir kurio ciklo kintamasis 'i' yra naudojamas bei greičiausiai tai yra fragmentas, kuriame padaryta klaida.

* C++ kalboje std::string taip lyginti negalima:if(D[i].vardas>D[j].vardas) Norint "abecėliškai" palyginti žodį, reikia naudojant ciklą praleisti sutampančias raidas ir tada palyginti pirmas nesutampančius simbolius. Pvz: int raide = 0;
while(D[i].vardas[raide] == D[j].vardas[raide])
{
      raide++;
}
if(D[i].vardas[raide] > D[j].vardas[raide])
{
      swap(D[i], D[j]);
}

* sizeof operatorius C++ kalboje naudojamas, kaip funkcija - klaida šioje vietoje: fd.get(eil, sizeof eil);turi būtifd.get(eil, sizeof(eil));

Taigi, sutvarkius rikiavimą ir laiko skaičiavimą (kas panašu ir yra šios užduoties pagrindinis akcentas), programa turėtų veikti arba bent jau duoti rezultatą artimą egzamine pateiktiems pavyzdžiams.

Nori sudalyvauti šioje temoje ir parašyti savo pranešimą? Prisijungti »