ematematikas
Kategorijos +Nauja tema Prisijungti        

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

Informatika Peržiūrų skaičius (365)

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();
}

0

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.

1

Norėdami rašyti žinutes privalote prisijungti!