SOI 2013. Die Schweizer Informatikolympiade



Ähnliche Dokumente
Programmierkurs Java

Java-Programmierung mit NetBeans

Papierverbrauch im Jahr 2000

Kulturelle Evolution 12

Deutsches Rotes Kreuz. Kopfschmerztagebuch von:

OECD Programme for International Student Assessment PISA Lösungen der Beispielaufgaben aus dem Mathematiktest. Deutschland

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

1 Vom Problem zum Programm

Objektorientierte Programmierung

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Das RSA-Verschlüsselungsverfahren 1 Christian Vollmer

Rock-Band. Einleitung. Scratch. In diesem Projekt lernst du, wie du deine eigenen Musikinstrumente programmieren kannst! Activity Checklist

Zwischenablage (Bilder, Texte,...)

Programmiervorkurs SS 2011 Technische Universität Darmstadt Jan Hendrik Burdinski, Felix Kerger

Spielmaterial. Hallo! Ich bin der kleine AMIGO und zeige euch, wie dieses Spiel funktioniert. Viel Spaß! von Liesbeth Bos

Wärmebildkamera. Arbeitszeit: 15 Minuten

Grundlagen der Theoretischen Informatik, SoSe 2008

Primzahlen und RSA-Verschlüsselung

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert

Einführung in die Programmierung

Anleitung über den Umgang mit Schildern

8. Berechnung der kalkulatorischen Zinsen

Viele Bilder auf der FA-Homepage

1. Was ihr in dieser Anleitung

Kontrollstrukturen und Funktionen in C

Zahlenwinkel: Forscherkarte 1. alleine. Zahlenwinkel: Forschertipp 1

Überblick. Lineares Suchen

Warum Sie jetzt kein Onlinemarketing brauchen! Ab wann ist Onlinemarketing. So finden Sie heraus, wann Ihre Website bereit ist optimiert zu werden

Anspruchsvolle Dreierausdrücke zum selbstständigen Lernen

Folgeanleitung für Fachlehrer

6.2 Scan-Konvertierung (Scan Conversion)

Mathematik VERA-8 in Bayern Testheft B: Realschule Wirtschaftsschule

Matrix42. Use Case - Sicherung und Rücksicherung persönlicher Einstellungen über Personal Backup. Version September

Daten sammeln, darstellen, auswerten

Thema 1: Fotos im Internet verwenden

Bedienungsanleitung für Mitglieder von Oberstdorf Aktiv e.v. zur Verwaltung Ihres Benutzeraccounts auf

1 topologisches Sortieren

Der Gabelstapler: Wie? Was? Wer? Wo?

Mein persönlicher Lerncheck: Einen Bericht schreiben

Serienbrieferstellung in Word mit Kunden-Datenimport aus Excel

Wir arbeiten mit Zufallszahlen

Proofreading Was solltest Du beim Korrekturlesen beachten?

Downloadfehler in DEHSt-VPSMail. Workaround zum Umgang mit einem Downloadfehler

Erstellen von x-y-diagrammen in OpenOffice.calc

M. Graefenhan Übungen zu C. Blatt 3. Musterlösung

Lineare Funktionen. 1 Proportionale Funktionen Definition Eigenschaften Steigungsdreieck 3

C++ Tutorial: Timer 1

ONLINE-AKADEMIE. "Diplomierter NLP Anwender für Schule und Unterricht" Ziele

Der Klassenrat entscheidet

Statuten in leichter Sprache

Professionelle Seminare im Bereich MS-Office

Persönliche Zukunftsplanung mit Menschen, denen nicht zugetraut wird, dass sie für sich selbst sprechen können Von Susanne Göbel und Josef Ströbl

Nina. bei der Hörgeräte-Akustikerin. Musterexemplar

Kinderarmut. 1. Kapitel: Kinderarmut in der Welt

1 Mathematische Grundlagen

Einführung in die Programmierung

Flow Session zum Entdecken Deines idealen Lebensstils

Erfahrungen mit Hartz IV- Empfängern

Folgeanleitung für Klassenlehrer

Zeichen bei Zahlen entschlüsseln

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

Sortieren durch Einfügen. Prof. Dr. W. Kowalk Sortieren durch Einfügen 1

Leichte-Sprache-Bilder

Bedienungsanleitung: Onlineverifizierung von qualifiziert signierten PDF-Dateien

Was man mit dem Computer alles machen kann

Unterrichtsmaterialien in digitaler und in gedruckter Form. Auszug aus: Übungsbuch für den Grundkurs mit Tipps und Lösungen: Analysis

AutoCAD Dienstprogramm zur Lizenzübertragung

Würfelt man dabei je genau 10 - mal eine 1, 2, 3, 4, 5 und 6, so beträgt die Anzahl. der verschiedenen Reihenfolgen, in denen man dies tun kann, 60!.

Deine Arbeit als Übersetzer bei lengoo Was erwartet Dich auf Deiner Reise mit lengoo? Was ist uns und unseren Kunden besonders wichtig?

Das Festkomitee hat die Abi-Seite neu konzipiert, die nun auf einem (gemieteten) Share Point Server

Theoretische Informatik SS 04 Übung 1

Kieselstein Meditation

7 Rechnen mit Polynomen

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

Barcodedatei importieren

Menü auf zwei Module verteilt (Joomla 3.4.0)

2) Geben Sie in der Anmeldemaske Ihren Zugangsnamen und Ihr Passwort ein

Welche Lagen können zwei Geraden (im Raum) zueinander haben? Welche Lagen kann eine Gerade bezüglich einer Ebene im Raum einnehmen?

Gezielt über Folien hinweg springen

Blog Camp Onlinekurs

Evangelisieren warum eigentlich?

Kreativ visualisieren

Erwin Grüner

Bitte wenden. Name: KURSARBEIT NR. 4 (10 DIFF GA) Seite 1

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet

sondern alle Werte gleich behandelt. Wir dürfen aber nicht vergessen, dass Ergebnisse, je länger sie in der Vergangenheit

Bitte lächeln! Invisalign. teen. Invisalign Teen ist da* Invisalign Teen TM. Die ideale Alternative zur Zahnspange für Teeneger - Patienten von heute!

Studienplatzbeschaffung

Datenübernahme von HKO 5.9 zur. Advolux Kanzleisoftware

Plotten von Linien ( nach Jack Bresenham, 1962 )

Profiler s Academy. Geistiges Menthol, das Sinn und Sinne weckt! 1 standfestigkeit. Unerschütterlichkeit in schwierigen Situationen

Übung Theoretische Grundlagen

Sichere Anleitung Zertifikate / Schlüssel für Kunden der Sparkasse Germersheim-Kandel. Sichere . der

Nina. 2. Ninas Mutter lebt nicht mit Nina und der Familie zusammen. Warum könnte das so sein? Vermute. Vielleicht ist sie. Möglicherweise.

Wir machen neue Politik für Baden-Württemberg

Kommentartext Medien sinnvoll nutzen

Transkript:

SOI Die Schweizer Informatikolympiade

Lösung SOI Wie schreibe ich eine gute Lösung? Bevor wir die Aufgaben präsentieren, möchten wir dir einige Tipps geben, wie eine gute Lösung für die theoretischen Aufgaben aussieht. Wenn nichts anderes in der Aufgabenstellung geschrieben steht, sollte deine Lösung folgende Punkte enthalten: Quellcode des Programms in Pascal, C, C++ oder Java. Dein Programm wird nicht durch einen PC getestet, sondern von Hand korrigiert. Darum sollte dein Programm ausführlich kommentiert sein und so elegant und einfach wie möglich sein. Verbringe nicht allzuviel Zeit damit, Eingabe und Ausgabe auf eine originelle Art zu behandeln (es ist nicht verboten, jedoch wird es dir nicht viele zusätzliche Punkte geben; andererseits kann deine Lösung dadurch unverständlicher werden). Beschreibung deiner Lösung. Das heisst nicht den Quellcode ins Deutsche zu übersetzen. Folgendes sollte enthalten sein: Beschreibung der Grundidee deiner Lösung ohne jegliche Implementationsdetails wie Variablennamen, Funktionen, etc. Beschreibung der benutzten Datenstruktur. Was und in welcher Form müssen wir abspeichern. Beschreibung des Algorithmus. In diesem Abschnitt beschreibst du, unter Benutzung der oben genannten Datenstruktur deine Funktionen, Prozeduren und sonstigen Variablen. Korrektheitsbeweis. Solange nicht anders angegeben erwarten wir, dass du zeigst, weshalb dein Algorithmus funktioniert. Schau zu, dass du vor allem die nicht offensichtlichen Teile deines Algorithmus darlegst. Zudem solltest du zeigen, dass dein Algorithmus immer terminiert (keine Endlosschleifen,...). Untersuchen der Laufzeit- und Speicherkomplexität. Die Laufzeitkomplexität gibt dir eine Abschätzung, wie schnell ein Programm abhängig von 1

SOI Lösung der Grösse der Eingabe läuft. Diese Laufzeit ist proportional zur Anzahl Grundoperationen wie Zuweisungen, Vergleichen von Variablen, arithmetischen Operationen, etc. Wir sind meist an der Laufzeit im schlechtesten Fall interessiert, was bedeutet wie lange dein Algorithmus maximal braucht. Die Speicherkomplexität ist analog dazu sie gibt eine Abschätzung, wie viel Speicher verbraucht wird in Abhängigkeit der Eingabegrösse. In der Komplexitätsanalyse sind wir nicht an exakten Grössen interessiert (es ist einerseits zu schwer und andererseits sehr sehr stark von der verwendeten Hardware abhängig). Stattdessen konzentrieren wir uns auf das Wachstum der Komplexität, welche in der O-Notation ausgedrückt wird. Die Funktion f(n) ist in O(g(n)), wenn f(n) mal eine Konstante immer kleiner als g(n) ist. 1 Nehmen wir beispielsweise an, dass ein Programm maximal T (n) = 0.5n 3 + 5n log n + 83 Mikrosekunden für eine Eingabe der Grösse n braucht. Da 0.5n 3 viel schneller ansteigt als 2 5n log n, können wir sagen, dass die Laufzeitkomplexität O(n 3 ) beträgt. (Was wir lesen können als Die Laufzeit des Algorithmus ist im schlimmsten Fall asymptotisch zu n 3. ) Wie du sieht, ist die multiplikative Konstante 0.5 dabei unbedeut T (n) ist nicht nur in O(n 3 ), viel mehr ist es auch in O(n 4 ), O(n 7 ),.... In der Laufzeitanalyse sind wir daher immer am kleinst möglichen O interessiert, das heisst, an der am langsamsten wachsenden Funktion. Die Laufzeit- und Speicherkomplexität zu finden ist generell recht einfach. Sobald du zwei verschachtelte Schleifen hast, die beide n mal durchlaufen werden, ergibt das eine Laufzeit von O(n 2 ). Ein weiteres Beispiel: 1 Mathematisch korrekte Definition: f(n) = O(g(n)) n 0 N, c R + ; n > n 0 ; f(n) c g(n) 2 Formell, lim n 0.5n 3 5n log n =. 2

Lösung SOI C: int i,j,c; int A[n]; Pascal: var i,j,c:integer; A:array[1..n] of integer; void main() { c = 0; for (i=1; i<=n; i++) for (j=i+1; j<=n; j++) if (A[i]<A[j]) c++; printf("%d\n", c); } c := 0; for i:=1 to n-1 do for j:=i+1 to n do if A[i]<A[j] then inc(c); writeln(c); Die äussere Schleife wird n 1 mal aufgerufen, die innere n i mal. Die Vergleichsoperation A[i] < A[j] wird somit (n 1) + (n 2) +... + 1 = n(n 1) 2 mal aufgerufen. Die Laufzeit beträgt somit O(n 2 ). Wir verwenden 3 Integer Variablen und ein Integer Array der Grösse n. Dadurch ist die Speicherkomplexität O(n). Ein Beispiel Aufgabe: Dir wird eine Folge von n ganzen Zahlen gegeben. Schreibe ein Programm, das entscheidet, ob die Summe einer zusammenhängenden Teilfolge gleich k ist. Lösung: Die simpelste Lösung ist alle möglichen Teilfolgen durchzuprobieren und anschliessend ihre Summe mit k zu vergleichen. var n,k:integer; { Input values } C:array[1..MaxN] of integer; { Input sequence } i,j,z,sum:integer; for i:=1 to N do { For each subsequence } for j:=i to N do 3

SOI Lösung sum:=0; for z:=i to j do sum:=sum+c[z]; { Compute its sum } if sum=k then writeln( Subsequence exists ); halt writeln( Subsequence does not exist ); Dieser Algorithmus ist sehr einfach zu implementieren und der Korrektheitsbeweis sollte auch nicht allzu schwer ausfallen. 3 Wie gross ist jedoch die Laufzeitkomplexität? Es ist leicht zu sehen, dass sum:=sum+c[z] die am häufigsten aufgerufene Operation ist. Sie wird für jedes Element jeder möglichen Teilfolge aufgerufen. Es gibt O(n 2 ) Teilfolgen mit je O(n) Elementen. Die Laufzeit beträgt demnach 4 O(n 3 ). Geht das auch schneller? Es ist einfach zu sehen, dass wir die Summe nicht jedes Mal neu berechnen muss. Die Summe C[i]+...+C[j 1]+C[j] erhalten wir auch durch hinzufügen des Wertes C[j] zur zuvor berechneten Summe C[i] +... + C[j 1]. Diese Idee ergibt uns folgendes Programm: for i:=1 to N do sum := 0; for j:=i to N do sum := sum + C[j]; { Now sum = C[i]+C[i+1]+...+C[j] } if sum=k then writeln( Subsequence exists ); halt writeln( Subsequence does not exist ); 3 Da wir die Summen aller möglichen Teilfolgen berechnen und diese mit k vergleichen. 4 Dies ist sogar die präziseste Laufzeitabschätzung: Für die genaue Anzahl Operationen erhalten wir. n n j i = n3 n 6 i=1 j=i 4

Lösung SOI Dieser Algorithmus ist mit O(n 2 ) Operationen einiges schneller. 5 Als nächstes werden wir eine kleine Optimierung einbringen: Sobald die Variable sum grösser als k wird, beenden wir die innere Schleife und fahren mit dem nächsten Durchlauf der äusseren Schleife fort: for i:=1 to N do sum := 0; j:=i; while (sum<k) and (j<=n) do { End the loop as soon } { as possible } sum := sum + C[j]; if sum=k then writeln( Subsequence exists ); halt j := j+1 writeln( Subsequence does not exist ); Leider wurde durch diese Optimierung die Laufzeitkomplexität nicht besser: Für grosse k tut unsere Optimierung nichts. Es gibt jedoch einen anderen Weg, wie wir den Algorithmus verbessern können: Nach dem Beenden der inneren while-schleife wirft unser Algorithmus den zuvor berechneten Wert für sum = C[i]+C[i+1]+...+C[j] weg und berechnet C[i+1]+C[i+2]... erneut. Da die while-schleife so schnell als möglich beendet wird, wissen wir, dass sum = C[i]+...+C[j] > k und C[i]+...+C[j 1] < k. Somit gilt C[i+1]+...+C[j 1] < k. Im nächsten Durchlauf der äusseren Schleife können wir für C[i+1]+...+C[j] die alte Summe sum nehmen, C[i] davon abziehen und damit weiterrechnen: var n,k:integer; { Input values } C:array[1..MaxN] of integer; { Input sequence } i,j,sum:integer; 5 Dies ist wieder die best mögliche Abschätzung der Laufzeit. Die Analyse ist ähnlich wie im Beispiel in der Einführung 5

SOI Lösung sum:=0; i:=1; j:=1; while (sum<>k) and (i<=n) do { Check if sum=k } { after decrementing } while (sum<k) and (j<=n) do { Enlarge the subsequence } sum := sum + C[j]; if sum=k then writeln( Subsequence exists ); halt j := j+1 sum := sum-c[i]; { Shrink the subsequence } i := i+1; if sum=k then writeln( Subsequence exists ) else writeln( Subsequence does not exist ); Wie hoch ist nun die Zeitkomplexität dieses Algorithmus? Die äussere Schleife wird maximal n mal aufgerufen. Die innere Schleife kann für jede äussere Schleife O(n) mal aufgerufen werden. Insgesamt kann die innere Schleife jedoch nur n mal aufgerufen werden, da j jedes mal erhöht und nie kleiner wird. Daher ist die Laufzeit dieses Algorithmus O(n). Die Speicherkomplexität bleibt bei O(n). Die Korrektheit des letzten Algorithmus kann folgendermassen bewiesen werden: Wir haben gezeigt, dass der O(n 3 ) Algorithmus korrekt war. Zudem ist jede unserer Optimierungen zulässig (was wir ebenfalls gezeigt haben). c SOI Team, 2008, www.soi.ch 6