IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Exercice France IOI


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Exercice France IOI
    Bonjour,

    Je sais que cet exercice a déjà été corrigé ici même, mais je ne cherche pas la correction, je cherche l'erreur dans mon programme.
    Je n'ai jusqu'a maintenant jamais eu de problèmes majeurs dans aucuns des exercices de France IOI mais avec celui ci, je peux pas vraiment tester des valeurs, et je n'ai que 80% de tests réussis.
    Voici l'énoncé :

    Ce que doit faire votre programme :

    nbGrenouilles numérotées de 1 à nbGrenouilles sont placées sur une ligne de départ. À chaque tour, on vous indique le numéro de la seule grenouille qui va sauter lors de ce tour, et la distance qu'elle va parcourir en direction de la ligne d'arrivée.

    Écrivez un programme qui détermine laquelle des grenouilles a été strictement en tête de la course au début du plus grand nombre de tours. Notez que comme on s'intéresse à qui est en tête au début de chaque tour, le bond du dernier tour ne sert à rien car même si la grenouille concernée passe en tête, la course est finie (il est purement honorifique selon la tradition algoréenne).
    LIMITES DE TEMPS ET DE MEMOIRE (Langage : C++)

    Temps : 1s sur une machine à 1Ghz.
    Mémoire : 16000 Ko.

    CONTRAINTES

    1 <= nbGrenouilles <= 100
    1 <= nbTours <= 1000
    1 <= distanceSauti <= 100
    ENTRÉE

    La première ligne de l'entrée contient un entier, le nombre de grenouilles nbGrenouilles qui participent à la course. Les grenouilles sont numérotées de 1 à nbGrenouilles.

    La deuxième ligne de l'entrée contient le nombre de tours nbTours de la course.

    Chacune des nbTours lignes suivantes décrit un tour par deux entiers séparés par un espace. Le premier entier est le numéro de la grenouille qui saute à ce tour, et le deuxième, est la distance parcourue par la grenouille lors de ce saut.
    SORTIE

    Vous devez afficher un entier sur la sortie : le numéro de la grenouille qui a été strictement en tête au début du plus grand nombre de tours. En cas d'égalité entre plusieurs grenouilles, choisissez celle dont le numéro est le plus petit.
    EXEMPLE

    entrée :
    4
    6
    2 2
    1 2
    3 3
    4 1
    2 2
    3 1
    sortie :
    2




    Et voici mon programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    int main() {
     
        int nbFrog, nbRounds, compteur=0, comparator=0;
        cin >> nbFrog >> nbRounds;
     
        int points[nbFrog];
        int jumps[nbFrog];
     
        for ( int d=0; d<nbFrog; d++){
            points[d]= 0;
            jumps[d]= 0;
        }
        for ( int x=0; x < nbRounds-1; x++ ){
     
            int frog, jump;
            cin >> frog >> jump;
     
            jumps[frog-1] += jump;
     
            for ( int c=0; c < nbFrog; c++ ){
     
                if (jumps[frog-1] > jumps[c]){
     
                    compteur ++;
                }
            }
            if ( compteur == nbFrog-1){
                points[frog-1] += 1;
            }
            compteur = 0;
        }
     
        for ( int h=0; h<nbFrog; h++){
            if ( points[h]>comparator){
                comparator = points[h];
            }
     
        }
        int winner = distance(points, find(points, points + nbFrog, comparator));
        cout << winner+1;
     
        /*cout << endl;
         for (int f=0; f<nbFrog; f++){
         cout << points[f] << " ";
         }
         cout << endl;
         for (int g=0; g<nbFrog; g++){
         cout << jumps[g] << " ";
         }*/
    }
    Voila, merci d'avance, et sachez que n'importe quelle remarque et critique sur le code est bienvenue

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Salut,

    quick&dirty en lisant l'énoncé mon code ressemblerait à (je n'ai pas particulièrement lu le tien désolé, les 2 premières lignes sont déjà fausses int points[nbFrog]; int jumps[nbFrog];)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    #include <iostream>
    #include <vector>
    #include <algorithm>
     
    struct Frog { unsigned int id; unsigned int distance; unsigned int winningTurns; };
    int main()
    {
      int nbFrogs, nbTurns;
      std::cin >> nbFrogs >> nbTurns;
      std::vector<Frog> frogs(nbFrogs);
      for (size_t i = 0; i < frogs.size(); ++i)
      {
        frogs[i].id = i+1;
        frogs[i].distance = 0;
        frogs[i].winningTurns = 0;
      }
      for (int i = 0; i < nbTurns; ++i)
      {
        int frog, distance;
        std::cin >> frog >> distance;
        frogs[frog-1].distance += distance;
        auto winningFrogThisTurn = std::max_element(frogs.begin(), frogs.end(), [](const Frog& f1, const Frog& f2){ return f1.distance < f2.distance; });
        ++(winningFrogThisTurn->winningTurns);
      }
      const auto winningFrog = std::max_element(frogs.cbegin(), frogs.cend(), [](const Frog& f1, const Frog& f2){ return f1.winningTurns < f2.winningTurns; });
      std::cout<<winningFrog->id;
    }
    testé sur http://cpp.sh/ j'ai 2 en sortie si c'est ce que tu attends ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Salut Bousk,

    Merci de ta réponse, mais comme je l'ai précisé, je ne cherche pas une autre solution. Je cherche à comprendre mon erreur.

    Aussi, pourquoi dis-tu que int points[nbFrog], jumps[nbFrog]; sont fausses ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Parce que cette syntaxe c'est un VLA d'une certaine version de C, qui n'a absolument jamais été valide dans toute version C++ confondue et je me demande donc bien d'où tu la sors.
    Partant de là, le reste de ton code tombe en (non)marche par hasard.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Les VLA sont surement acceptés car tu as eu 80/100.
    Par contre la boucle lignes 24 à 30 suppose que la grenouille en tête est celle qui vient d'avancer, ça n'est pas forcément le cas. Il faut donc rechercher pour toutes les grenouilles celle qui est en tête puis si elle est seule lui donner un point.
    Et comme précisé dans l'énoncé, il ne faut donner de point lors de la dernière itération ou bien effectuer la recherche avant de faire avancer la grenouille.

  6. #6
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        std::cin >> frog >> distance;
        frogs[frog-1].distance += distance;
        auto winningFrogThisTurn = std::max_element(frogs.begin(), frogs.end(), [](const Frog& f1, const Frog& f2){ return f1.distance < f2.distance; });
        ++(winningFrogThisTurn->winningTurns);
    Attention, l'énoncé indique :
    « Écrivez un programme qui détermine laquelle des grenouilles a été strictement en tête de la course au début du plus grand nombre de tours. Notez que comme on s'intéresse à qui est en tête au début de chaque tour, le bond du dernier tour ne sert à rien car même si la grenouille concernée passe en tête, la course est finie »

    Donc :
    • La recherche de la grenouille strictement en tête doit être faite avant le saut.
    • Comme on recherche la grenouille strictement en tête (s'il y en a une), il ne faut pas utiliser std::max_element ici.


    Je propose la correction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    // EDIT 2016-12-24-23h13 : amélioration de getNumberInRange
    // EDIT 2016-12-25-12h29 : renommage de getNumberInRange en readNumberInRange
    // EDIT 2016-12-26-13h18 : amélioration de strictlyMaxElement
     
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <sstream>
    #include <stdexcept>
    #include <vector>
     
    //! \remark If the strictly largest element does not exist, return last iterator.
    template<class ForwardIt, class Compare>
    ForwardIt strictlyMaxElement(ForwardIt first, ForwardIt last, Compare cmp)
    {
    	if(first == last)
    		return last;
    	ForwardIt largest = first;
    	bool strictlyLargest = true;
    	for(++first; first != last; ++first) {
    		if(cmp(*largest, *first)) {
    			largest = first;
    			strictlyLargest = true;
    		} else {
    			strictlyLargest = strictlyLargest && cmp(*first, *largest);
    		}
    	}
    	return strictlyLargest ? largest : last;
    }
     
    template<class CharT, class Traits, class NumberT>
    NumberT readNumberInRange(std::basic_istream<CharT, Traits>& input, NumberT min, NumberT max)
    {
    	NumberT result;
    	input >> result;
     
    	if(input.eof()) {
    		throw std::runtime_error("Fail to read a number from input stream: end of file.");
    	} else if(input.bad()) {
    		throw std::runtime_error("Fail to read a number from input stream: bad state.");
    	} else if(input.fail()) {
    		input.clear(); // unset failbit
    		input.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip bad input
    		throw std::runtime_error("Input error when reading a number: bad format.");
    	} else if(result < min || result > max) {
    		std::ostringstream oss;
    		oss << "Input error: the number (" << result
    		    << ") must be between " << min << " and " << max << '.';
    		throw std::runtime_error(oss.str());
    	}
     
    	return result;
    }
     
    struct Frog {
    	typedef unsigned DistanceType;
    	typedef unsigned TurnCountType;
    	DistanceType  totalDistance    = 0;
    	TurnCountType winningTurnCount = 0;
    };
     
    int main()
    {
    	try {
    		const size_t              frogNumber = readNumberInRange(std::cin, 1, 100);
    		const Frog::TurnCountType turnNumber = readNumberInRange(std::cin, 1, 1000);
    		std::vector<Frog> frogs(frogNumber);
    		for(Frog::TurnCountType k = 0; k < turnNumber; ++k)
    		{
    			const auto winningFrogIt = strictlyMaxElement(std::begin(frogs), std::end(frogs),
    				[](const Frog& f1, const Frog& f2){return f1.totalDistance < f2.totalDistance;});
    			if(winningFrogIt != std::end(frogs))
    				++(winningFrogIt->winningTurnCount);
    			const size_t             frogId       = readNumberInRange(std::cin, 1, int(frogNumber));
    			const Frog::DistanceType jumpDistance = readNumberInRange(std::cin, 1, 100);
    			frogs[frogId - 1].totalDistance += jumpDistance;
    		}
    		const auto winningFrogIt = std::max_element(frogs.cbegin(), frogs.cend(), // GCC 4.9.2: std::cbegin and std::cend do not exist yet.
    			[](const Frog& f1, const Frog& f2){return f1.winningTurnCount < f2.winningTurnCount;});
    		const size_t winningFrogId = std::distance(frogs.cbegin(), winningFrogIt) + 1;
    		std::cout << winningFrogId;
    		return 0;
    	} catch(const std::exception& e) {
    		std::cerr << e.what() << '\n';
    		return 1;
    	}
    }
    Citation Envoyé par obiG00 Voir le message
    Je sais que cet exercice a déjà été corrigé ici même
    Par curiosité : Où ça ?

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 3
    Points : 1
    Points
    1

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Pyramidev Voir le message
    Attention, l'énoncé indique :
    « Écrivez un programme qui détermine laquelle des grenouilles a été strictement en tête de la course au début du plus grand nombre de tours. Notez que comme on s'intéresse à qui est en tête au début de chaque tour, le bond du dernier tour ne sert à rien car même si la grenouille concernée passe en tête, la course est finie »

    Donc :
    • La recherche de la grenouille strictement en tête doit être faite avant le saut.
    • Comme on recherche la grenouille strictement en tête (s'il y en a une), il ne faut pas utiliser std::max_element ici.
    Au lieu d'over-engineerer et perdre un débutant il suffit de faire démarrer la boucle de comptage des tours à 1, ou décrémenter le nombre de tour par rapport à l'entrée utilisateur.
    Si tu computes la grenouille victorieuse, ta grenouille 1 aura toujours une avance de 1 tour victorieux, ton premier tour de boucle. C'est voulu ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Citation Envoyé par Bousk Voir le message
    il suffit de faire démarrer la boucle de comptage des tours à 1, ou décrémenter le nombre de tour par rapport à l'entrée utilisateur.
    Le problème, c'est que le nombre de saisies de couple (numéro de grenouille, distance de saut) est égal au nombres de tours. Donc, si on ne passait dans la boucle que nbTours-1 fois, il faudrait faire saisir encore un couple (numéro de grenouille, distance de saut) avant ou après cette boucle. Cela ferait une répétition inutile dans le code.

    Citation Envoyé par Bousk Voir le message
    Si tu computes la grenouille victorieuse, ta grenouille 1 aura toujours une avance de 1 tour victorieux, ton premier tour de boucle. C'est voulu ?
    Elle n'aura pas une avance de 1 tour victorieux.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    			const auto winningFrogIt = strictlyMaxElement(std::begin(frogs), std::end(frogs),
    				[](const Frog& f1, const Frog& f2){return f1.totalDistance < f2.totalDistance;});
    			if(winningFrogIt != std::end(frogs))
    				++(winningFrogIt->winningTurnCount);
    Dans le premier passage dans la boucle, il y a plusieurs grenouilles à égalité pour la première place (en fait, toutes), donc winningFrogIt == std::end(frogs).

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    En ce cas une solution toute simple est d'ajouter une lecture en dehors de la boucle après avoir itérer sur le nombre de tour voulus (l'entrée-1).
    Si tu veux pas répéter du code, tu peux faire une fonction si tu le souhaites.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Réponses: 13
    Dernier message: 25/06/2016, 13h53
  2. Allocation de mémoire trop importante[france ioi]
    Par anorexia dans le forum Débuter
    Réponses: 0
    Dernier message: 21/02/2009, 16h17
  3. Une déclaration pour la survie du jeu vidéo en France
    Par Freakazoid dans le forum DirectX
    Réponses: 1
    Dernier message: 30/10/2002, 14h31
  4. Pouvez vous m'aider a resoudres ces 3 exercices
    Par algorithmique dans le forum Algorithmes et structures de données
    Réponses: 11
    Dernier message: 09/08/2002, 17h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo