Il s'agit essentiellement d'un graphe de dépendances où chaque billet représente un nœud et où les src y dst L'aéroport représente des liens dirigés, utilisez donc un tri topologique pour déterminer l'ordre des vols.
EDIT : Bien que, puisqu'il s'agit d'un billet d'avion et que vous savez que vous avez réellement établi un itinéraire, vous pourriez physiquement effectuer un tri par date et heure de départ en UTC.
EDIT2 : En supposant que chaque aéroport pour lequel vous avez un billet utilise un code à trois caractères, vous pouvez utiliser l'algorithme décrit ici ( Trouvez trois nombres apparaissant une seule fois ) pour déterminer les deux aéroports uniques en xant tous les aéroports ensemble.
EDIT3 : Voici un peu de C++ pour résoudre ce problème en utilisant la méthode xor. L'algorithme global est le suivant, en supposant un codage unique de l'aéroport en un entier (soit en supposant un code d'aéroport à trois lettres, soit en codant la localisation de l'aéroport en un entier utilisant la latitude et la longitude) :
D'abord, faites un XOR de tous les codes d'aéroport ensemble. Cela devrait être égal à l'aéroport source initial XOR l'aéroport de destination finale. Comme nous savons que l'aéroport initial et l'aéroport final sont uniques, cette valeur ne doit pas être nulle. Puisqu'elle n'est pas nulle, il y aura au moins un bit activé dans cette valeur. Ce bit correspond à un bit qui est activé dans l'un des aéroports et non dans l'autre ; on l'appelle le bit indicateur.
Ensuite, définissez deux compartiments, chacun avec la valeur XORed de la première étape. Maintenant, pour chaque billet, mettez dans le panier chaque aéroport selon qu'il a le bit de désignation activé ou non, et faites le XOR du code de l'aéroport avec la valeur dans le panier. Gardez également la trace, pour chaque case, du nombre d'aéroports d'origine et d'aéroports de destination qui sont entrés dans cette case.
Après avoir traité tous les billets, choisissez l'un des godets. Le nombre d'aéroports sources envoyés dans ce compartiment doit être supérieur ou inférieur d'une unité au nombre d'aéroports de destination envoyés dans ce compartiment. Si le nombre d'aéroports sources est inférieur au nombre d'aéroports de destination, cela signifie que l'aéroport source initial (le seul aéroport source unique) a été envoyé dans l'autre godet. Cela signifie que la valeur dans le seau actuel est l'identifiant de l'aéroport source initial ! Inversement, si le nombre d'aéroports de destination est inférieur au nombre d'aéroports sources, cela signifie que l'aéroport de destination final a été envoyé dans l'autre godet, donc le godet actuel est l'identifiant de l'aéroport de destination final !
struct ticket
{
int src;
int dst;
};
int get_airport_bucket_index(
int airport_code,
int discriminating_bit)
{
return (airport_code & discriminating_bit)==discriminating_bit ? 1 : 0;
}
void find_trip_endpoints(const ticket *tickets, size_t ticket_count, int *out_src, int *out_dst)
{
int xor_residual= 0;
for (const ticket *current_ticket= tickets, *end_ticket= tickets + ticket_count; current_ticket!=end_ticket; ++current_ticket)
{
xor_residual^= current_ticket->src;
xor_residual^= current_ticket->dst;
}
// now xor_residual will be equal to the starting airport xor ending airport
// since starting airport!=ending airport, they have at least one bit that is not in common
//
int discriminating_bit= xor_residual & (-xor_residual);
assert(discriminating_bit!=0);
int airport_codes[2]= { xor_residual, xor_residual };
int src_count[2]= { 0, 0 };
int dst_count[2]= { 0, 0 };
for (const ticket *current_ticket= tickets, *end_ticket= tickets + ticket_count; current_ticket!=end_ticket; ++current_ticket)
{
int src_index= get_airport_bucket_index(current_ticket->src, discriminating_bit);
airport_codes[src_index]^= current_ticket->src;
src_count[src_index]+= 1;
int dst_index= get_airport_bucket_index(current_ticket->dst, discriminating_bit);
airport_codes[dst_index]^= current_ticket->dst;
dst_count[dst_index]+= 1;
}
assert((airport_codes[0]^airport_codes[1])==xor_residual);
assert(abs(src_count[0]-dst_count[0])==1); // all airports with the bit set/unset will be accounted for as well as either the source or destination
assert(abs(src_count[1]-dst_count[1])==1);
assert((src_count[0]-dst_count[0])==-(src_count[1]-dst_count[1]));
int src_index= src_count[0]-dst_count[0]<0 ? 0 : 1;
// if src < dst, that means we put more dst into the source bucket than dst, which means the initial source went into the other bucket, which means it should be equal to this bucket!
assert(get_airport_bucket_index(airport_codes[src_index], discriminating_bit)!=src_index);
*out_src= airport_codes[src_index];
*out_dst= airport_codes[!src_index];
return;
}
int main()
{
ticket test0[]= { { 1, 2 } };
ticket test1[]= { { 1, 2 }, { 2, 3 } };
ticket test2[]= { { 1, 2 }, { 2, 3 }, { 3, 4 } };
ticket test3[]= { { 2, 3 }, { 3, 4 }, { 1, 2 } };
ticket test4[]= { { 2, 1 }, { 3, 2 }, { 4, 3 } };
ticket test5[]= { { 1, 3 }, { 3, 5 }, { 5, 2 } };
int initial_src, final_dst;
find_trip_endpoints(test0, sizeof(test0)/sizeof(*test0), &initial_src, &final_dst);
assert(initial_src==1);
assert(final_dst==2);
find_trip_endpoints(test1, sizeof(test1)/sizeof(*test1), &initial_src, &final_dst);
assert(initial_src==1);
assert(final_dst==3);
find_trip_endpoints(test2, sizeof(test2)/sizeof(*test2), &initial_src, &final_dst);
assert(initial_src==1);
assert(final_dst==4);
find_trip_endpoints(test3, sizeof(test3)/sizeof(*test3), &initial_src, &final_dst);
assert(initial_src==1);
assert(final_dst==4);
find_trip_endpoints(test4, sizeof(test4)/sizeof(*test4), &initial_src, &final_dst);
assert(initial_src==4);
assert(final_dst==1);
find_trip_endpoints(test5, sizeof(test5)/sizeof(*test5), &initial_src, &final_dst);
assert(initial_src==1);
assert(final_dst==2);
return 0;
}
7 votes
"Des milliards de transferts... Vous ne vous arrêtez pas deux fois dans le même aéroport" Je ne pense pas qu'il y ait autant d'aéroports.
1 votes
James - Je pense qu'il y a un logiciel de traduction au travail ici. "milliards" = beaucoup ? Inversement, ORD -> LAX -> SLC -> DEN -> etc -> etc -> etc ... une explosion de permutations pourrait donner des "milliards" de routes possibles. OP ?
0 votes
Cela semble facile en O(n^2), et compliqué mais possible en O(nlogn) ou un peu moins en adaptant le tri par fusion, non ?
2 votes
Ça sent le travail à domicile pour moi, mais qu'est-ce que j'en sais...
4 votes
+1 pour contrer les votes négatifs, et les votes serrés, sans explication. (Si vous voulez être grincheux : laissez la question de ce gars tranquille)
0 votes
@Bob : bien sûr, des milliards de routes possibles, mais pas de transferts, puisqu'on ne peut visiter un aéroport qu'une seule fois. Selon la CIA (voir fr.wikipedia.org/wiki/Aéroport ), il y a environ 44 000 aéroports. Cela fait quoi, 44.000 - 1 transferts disponibles et 44.000 ! routes différentes ?
0 votes
Les algorithmes de tri par comparaison pour construire la liste des billets elle-même ne sont pas la bonne approche, car il n'est pas possible de comparer la plupart des paires de billets. De plus, lorsque vous réussissez à comparer deux billets, vous savez qu'il n'y a pas de billet entre les deux, puisque ticket1.destination=ticket2.source ou ticket2.destination=ticket1.source. En ce qui concerne la table de consultation des aéroports elle-même, une table de hachage est presque certainement le bon choix. Bucketsort sur les noms d'aéroports est aussi O(1), mais résulte probablement en un algorithme plus lent, en pratique.
0 votes
Bonne question. Je l'aime bien.
12 votes
1) Trier les billets par heure de départ, 2) Le point de départ du premier billet est votre aéroport de départ, et le point d'arrivée du dernier billet est votre aéroport d'arrivée ;)
0 votes
@Nick : il n'y a pas d'information sur l'heure de départ, seulement les noms de src et dst
0 votes
Je faisais de l'humour. C'est pas grave. :)
2 votes
Si vous avez oublié votre destination finale, alors vous n'avez pas vos bagages (puisqu'ils se trouvent dans un aéroport inconnu). Étant donné le grand nombre de billets concernés, vous auriez dû les ranger dans vos bagages. Par conséquent, vous n'avez pas les billets, et la question est sans objet.