Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème de tri

identifier les bacs -France ioi-

Sujet résolu
5 juillet 2015 à 6:15:31

Bonjour,

Il y a des mois que je suis resté bloqué en face d'un problème qui demande de trier deux tableaux :

Stocker les niveaux de pollution des différents bacs en attente d'être emportés est utile pour évaluer par exemple la quantité de polluant que vous avez en stock à un moment donné, mais ne conserver que cette valeur pour chaque bac limite ce que vous pouvez faire avec ces données. Impossible de savoir par exemple depuis quand un bac est dans votre stock, ce qu'il contient exactement, etc.

Pour résoudre ce problème, vous avez décidé d'identifier chaque bac par un code numérique. A partir de ce code numérique, vous pourrez ainsi retrouver toutes sortes d'informations sur chaque bac.

Vous avez mis à jour vos données décrivant les niveaux de pollution des bacs, pour y inclure les identifiants des bacs. Il faut maintenant mettre à jour votre programme de tri pour qu'il gère ces identifiants.

LIMITES DE TEMPS ET DE MEMOIRE (Langage : C)

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

CONTRAINTES

  • 1 <= N <= 20 000, où est le nombre de bacs décrits dans les données.
  • 0 <= B <= 100 000, où B est le code d'identification d'un bac.
  • 0 <= P <= 108, où P  est le niveau de pollution d'un bac.

ENTRÉE

La première ligne de l'entrée contient un entier : le nombre N de bacs décrits dans les données.

Chacune des N lignes suivantes contient deux entiers séparés par un espace : le code d'identification B et le niveau de pollution P d'un bac.

SORTIE

Vous devez afficher N lignes sur la sortie, contenant chacune deux entiers séparés par un espace : le code d'identification et le niveau de pollution d'un bac. Ces lignes donnent les valeurs triées par ordre croissant du niveau de pollution des bacs. Si deux bacs ont le même niveau de pollution, affichez les par ordre croissant de leur code d'identification.

EXEMPLE

entrée :

6
1 6
2 3
4 12
3 7
5 25
7 18

sortie :

2 3
1 6
3 7
4 12
7 18
5 25


bon, j'ai réussi à écrire un code qui affiche correctement mais pour 3 tests, il prend plus que 0.5s

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
  cin.sync_with_stdio(false);
  int nbre;
  cin>>nbre;
  int tableau1[nbre];
  int tableau2[nbre];

  for(int i=0;i<nbre;i++)
  {
    cin>>tableau1[i]>>tableau2[i];
    if(i>0)
    {int c=0;
      for(int b=i-1;b>=0;b--)
      {
        if(tableau2[b]>tableau2[i-c])
        {
          int rapport=tableau2[i-c];
          int rapport1=tableau1[i-c];;
          tableau2[i-c]=tableau2[b];
          tableau1[i-c]=tableau1[b];
          tableau2[b]=rapport;
          tableau1[b]=rapport1;
        }
        else if(tableau2[b]==tableau2[i-c])
        {
          if(tableau1[b]>tableau1[i-c])
          {
            
         int  rapport1=tableau1[i-c];
          
          tableau1[i-c]=tableau1[b];
          
          tableau1[b]=rapport1;
          }
        }
        else
        {
          b=-1;
        }
        c++;
      }
    }
  }

 for(int i=0;i<nbre;i++)
  {    
      cout<<tableau1[i]<<" "<<tableau2[i]<<endl;
  }
}
          
        

Résultat de l'évaluation [Serveur principal]

Test 1 Succès
Exécuté en 0 secondes
100%
Test 2 Succès
Exécuté en 0 secondes
100%
Test 3 Succès
Exécuté en 0 secondes
100%
Test 4 Succès
Exécuté en 0 secondes
100%
Test 5 Succès
Exécuté en 0.35 secondes
100%
Test 6 Succès
Exécuté en 0.01 secondes
100%
Test 7 Succès
Exécuté en 0.2 secondes
100%
Test 8 Succès
Exécuté en 0.06 secondes
100%
Test 9 Échec
Votre programme a dépassé la limite de temps. 
Cela peut venir de deux raisons :
- soit il est trop lent pour passer ce test dans la limite de temps du sujet
- soit il boucle indéfiniment et ne se termine jamais
0%
Test 10 Échec
Votre programme a dépassé la limite de temps. 
Cela peut venir de deux raisons :
- soit il est trop lent pour passer ce test dans la limite de temps du sujet
- soit il boucle indéfiniment et ne se termine jamais
0%
Test 11 Échec
Votre programme a dépassé la limite de temps. 
Cela peut venir de deux raisons :
- soit il est trop lent pour passer ce test dans la limite de temps du sujet
- soit il boucle indéfiniment et ne se termine jamais
0%
 
TOTAL Échec Vous avez réussi 8 tests sur 11. 73%
             

Je ne sais pas comment je dois faire pour le rendre plus rapide, c'est pour cela que je demande votre aide.

merci d'avance

-
Edité par garmel 5 juillet 2015 à 6:29:25

  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 8:11:19

garmel a écrit:

LIMITES DE TEMPS ET DE MEMOIRE (Langage : C)

#include<iostream>
#include<algorithm>

En C ou en C++ ?

En plus, tu inclus algorithm qui contient des fonctions de tri. Pourquoi ne pas les utiliser ?

Sinon, le tri par insertion n'est pas le plus rapide des tris vu que tu n'est pas sur un programme à flux (toutes les données te sont accessibles instantanément). Récupère toutes tes données puis effectue un tri rapide ou un tri par fusion (ça devrait passer dans toute la mémoire qu'on t'autorise à avoir). Sinon, tu peux stocker tes données dans une structure/classe et trier un tableau d'identifiants interne (l'indice de ta structure). Les copies seront bien moins importantes et ça te fera gagner un temps précieux.

-
Edité par anolya 5 juillet 2015 à 8:14:51

  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 12:35:14

En fait, j'ai utiliser "sort", "tri rapide", "tri par fusion", mais c'est toujours le 9 ème test qui prend plus que 0.5 s
  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 13:17:06

Je pense que tu dois avoir des soucis de cache. Tes 2 tableaux sont éloignés en mémoire l'un de l'autre et tu les modifies en même temps. Si, à chaque fois, tu as du cache miss, tu risques d'écraser ton autre tableau et donc tu te retrouveras avec un autre cache miss. De ce fait, le temps d'exécution va être beaucoup plus important.

Je viens de coder un truc. Si tu avais l'endroit où je peux le tester pour vérifier qu'il répond bien aux 12 tests... (histoire que je ne dise pas de bêtises et que je ne te ponde pas la solution toute faite)

  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 13:52:44

Malheureusement, seulement si vous avez un compte et si vous avez déjà débloquer le 3 ème niveau.
  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 17:59:40

Enfin, résolu...En effet, merci beaucoup anolya de me faire connaître le tri par fusion....Il est le plus rapide dont la complexité est minimale
  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 18:19:59

Attention, même si le tri par fusion a une complexité en O(n ln(n)), même dans le pire des cas, ce n'est pas un tri sur place (contrairement au quick sort). En effet, on a besoin, au minimum, de la moitié de la taille du tableau à trier en mémoire supplémentaire.

-
Edité par anolya 5 juillet 2015 à 23:17:59

  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 23:16:46

anolya a écrit:

Attention, même si le tri par fusion a une complexité en O(ln(n)), même dans le pire des cas


Ça serait tellement beau… :'(

O(n * log(n))

-
Edité par Mad scientist 5 juillet 2015 à 23:16:58

  • Partager sur Facebook
  • Partager sur Twitter
Un vrai cours de: (C | C++ | Haskell débutant | Haskell intermédiaire | Rust).
5 juillet 2015 à 23:17:46

Ah oui, oublié le n, je l'ajoute.
  • Partager sur Facebook
  • Partager sur Twitter
5 juillet 2015 à 23:19:09

Ah tu as gâché mes rêves. :lol:
  • Partager sur Facebook
  • Partager sur Twitter
Un vrai cours de: (C | C++ | Haskell débutant | Haskell intermédiaire | Rust).
10 août 2024 à 13:39:23 - Message modéré pour le motif suivant : Merci de créer votre propre sujet


10 août 2024 à 15:26:45

@KimKossiAfangnike Bonjour,  merci de ne pas squatter le sujet résolu des autres, créer votre propre sujet dans le respect des règles du forum à savoir qu'un message commence par des règles de politesses (Un bonjour ou des salutations à la communauté et se termine par des remerciements par avances pour les futures réponses), la description de votre problème et le code que vous avez écrit inséré sur le forum à l'aide de l'outil d'intégration de code soit le bouton code </>.

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Liens conseillés

  • Partager sur Facebook
  • Partager sur Twitter