108 lines
4.7 KiB
Markdown
108 lines
4.7 KiB
Markdown
# Vollgeladen
|
|
|
|
## Lösungsidee
|
|
|
|
Da die niedrigste Bewertung möglichst hoch sein soll, sollte zuerst versucht
|
|
eine Route mit einer Mindestbewertung von 5.0 zu bilden. Scheitert dies wird
|
|
es mit 4.9, 4.8, ..., 0.1 versucht. Das Routenbildung mit einer bestimmten
|
|
Mindestbewertung kann aus zwei Gründen fehlschlagen:
|
|
|
|
- innerhalb der 6 Stunden Fahrzeit gibt es kein Hotel mit der Mindestbewertung
|
|
- an mehr als 4 Hotels muss gehalten werden
|
|
|
|
## Umsetzung
|
|
|
|
Die Lösungsidee wird in C implementiert. Eine Hilfsfunktion der
|
|
"advanced C standard library", die Textdateien ausliest, wird außerdem verwendet.
|
|
Der Quelltext der Library ist im Ordner "lib/advanced_C_standard_library" oder
|
|
[online](https://git.zinkel.org/MrGeorgen/advanced_C_standard_library) erhältlich.
|
|
Das Programm erhält als Argumente eine beliebige Anzahl Dateipfade zu Eingabedateien.
|
|
Mit einer for-Schleife wird über die Dateipfade iteriert. In der Schleife wird die
|
|
Eingabedatei ausgelesen. Die Anzahl der Hotels und die Gesamtfahrzeit werden jeweils
|
|
in einer Variable abgespeichert. Anschließend wird ein Array mit Strukturen die Hotels
|
|
darstellen befüllt. In einer do-while-Schleife wird mit einer Bewertung von
|
|
5.0, 4.9, ..., 0.1 eine Route zu bilden. Wenn dies bei einer Bewertung erfolgreich
|
|
ist wird die Schleife beendet. In dieser Schleife ist wiederum eine for-Schleife
|
|
die über die Hotels iteriert, worin das letzte Hotel gespeichert wird, das
|
|
mindestens die angestrebte Bewertung hat.
|
|
Ist das Hotel allerdings mehr als 6 Stunden vom letzten Haltepunkt entfernt,
|
|
muss das letzte Hotel verwendet werden an dem das Halten möglich ist, falls dieses
|
|
vorhanden ist und höchtens an drei Hotels schon gehalten wurde,
|
|
ansonsten muss mit der nächsten Bewertung fortgefahren werden.
|
|
Nachdem eine Route gefunden wurde, wird diese ausgeben und eventuell mit der
|
|
näcshten Eingabedatei fortgefahren.
|
|
|
|
## Beispiele
|
|
|
|
Ergebnisse für die Beispieldaten:
|
|
|
|
```
|
|
hotels1.txt:
|
|
Entfernung vom Start: 347 Minuten, Bewertung: 2.7
|
|
Entfernung vom Start: 687 Minuten, Bewertung: 4.4
|
|
Entfernung vom Start: 1007 Minuten, Bewertung: 2.8
|
|
Entfernung vom Start: 1360 Minuten, Bewertung: 2.8
|
|
hotels2.txt:
|
|
Entfernung vom Start: 341 Minuten, Bewertung: 2.3
|
|
Entfernung vom Start: 700 Minuten, Bewertung: 3.0
|
|
Entfernung vom Start: 1053 Minuten, Bewertung: 4.8
|
|
Entfernung vom Start: 1380 Minuten, Bewertung: 5.0
|
|
hotels3.txt:
|
|
Entfernung vom Start: 360 Minuten, Bewertung: 1.0
|
|
Entfernung vom Start: 717 Minuten, Bewertung: 0.3
|
|
Entfernung vom Start: 1076 Minuten, Bewertung: 3.8
|
|
Entfernung vom Start: 1433 Minuten, Bewertung: 1.7
|
|
hotels4.txt:
|
|
Entfernung vom Start: 340 Minuten, Bewertung: 4.6
|
|
Entfernung vom Start: 676 Minuten, Bewertung: 4.6
|
|
Entfernung vom Start: 1032 Minuten, Bewertung: 4.9
|
|
Entfernung vom Start: 1316 Minuten, Bewertung: 4.9
|
|
hotels5.txt:
|
|
Entfernung vom Start: 317 Minuten, Bewertung: 5.0
|
|
Entfernung vom Start: 636 Minuten, Bewertung: 5.0
|
|
Entfernung vom Start: 987 Minuten, Bewertung: 5.0
|
|
Entfernung vom Start: 1286 Minuten, Bewertung: 5.0
|
|
```
|
|
|
|
## Quelltext
|
|
|
|
```
|
|
int main() {
|
|
uint_least8_t rating = 50;
|
|
do {
|
|
// Minuten die das letzte Hotel, bei dem angehalten wurde, vom Start entfertn ist
|
|
uint_least16_t lastHotelMinutes = 0;
|
|
// Zeiger zum letzten Hotel, dessen Bewertung mindestens "rating" ist.
|
|
struct hotel *possibleStop = NULL;
|
|
stoppedHotels = 0; // setzt Anzahl der Stops zurück
|
|
|
|
// iteriert über die Hotels
|
|
for(struct hotel *currentHotel = hotels; currentHotel - hotels < numberHotels; ++currentHotel) {
|
|
|
|
/* Wenn das aktuelle Hotel mehr als 360 Minuten vom letzten Hotel entfernt ist,
|
|
* muss das letzte Hotel verwendet werden an dem das Halten möglich war.*/
|
|
if(currentHotel->minutes - lastHotelMinutes > 360) {
|
|
/* Wenn das Halten nicht möglich ist oder bereits schon viermal
|
|
* gehalten wurde, muss es mit einer niedrigeren Bewertung versucht
|
|
* werden.*/
|
|
if(possibleStop == NULL || stoppedHotels >= 4) break;
|
|
// hängt das Hotel der Route an
|
|
hotelRoute[stoppedHotels] = *possibleStop;
|
|
lastHotelMinutes = possibleStop->minutes;
|
|
// springt in der Schleife zurück zum Hotel, an dem gestoppt wurde
|
|
currentHotel = possibleStop;
|
|
++stoppedHotels;
|
|
}
|
|
// Wenn die Bewertung hoch genug ist, kann gestoppt werden.
|
|
if(currentHotel->rating >= rating) possibleStop = currentHotel;
|
|
}
|
|
--rating;
|
|
/* Schleife läuft solange "rating" mindestens Eins ist, da es keine niedrigeren Bewertungen
|
|
* gibt. Wenn das letzte Hotel höchtens 360 Minuten vom Zielort entfernt ist, wurde
|
|
* erfolgreich eine Route gefunden und die Schleife wird beendet. Allerdings wird dies nur
|
|
* überprüft, wenn überhaupt an einem Hotel gehalten wurde, um den Zugriff auf nicht
|
|
* definierten Speicher zu vermeiden.*/
|
|
} while(rating && (!stoppedHotels || totalMinutes - hotelRoute[stoppedHotels - 1].minutes > 360));
|
|
}
|
|
```
|