KSP.sk

Korešpondenčný seminár z programovania

Článok
Tlač

Ako má vyzerať odovzdaný program

Program má čítať zo štandardného vstupu (stdin, resp. input, inak povedané klávesnice v konzole), písať na štandardný výstup (stdout, resp. output, inak povedané obrazovku). Výstup musí dodržiavať formát uvedený v zadaní. A za každým riadkom na výstupe musí byť znak nového riadku (v C++ '\n', v Pascale/Jave/C# použite writeln/println/WriteLine). Vo svojom riešení sa nemusíš zaoberať kontrolovaním správnosti vstupných údajov. Súbor sa môže volať ľubovoľne, pri submitovaní je vždy jasné, ktorú úlohu submituješ.

Počas behu sa musí tvoje riešenie správať slušne. Zakázaný je akýkoľvek prístup k súborovému systému (na vstup a výstup sa používa štandardný vstup a výstup), prístup do pamäte testovača, snaha akýmkoľvek spôsobom narušiť jeho fungovanie a všetky podobné aktivity. Explicitne je zakázané používať viac ako 1 thread, t. j. volať fork().

Operačný systém a kompilátory na počítači, ktorý testuje riešenia

Vaše riešenia testujeme pod Debian Linuxom, na počítači, ktorý je vybavený 64bitovým procesorom. Pre jazyky používame kompilátory s nasledovnými nastaveniami:

C: gcc -static -O2 -lm riesenie.c
C++: g++ -static -O2 riesenie.cc
Pascal: fpc -Sg -O2 riesenie.pas
Java: javac riesenie.java
C#: mcs riesenie.cs

Príklady korektných programov

Ako riešenie úlohy "na vstupe je zopár malých celých čísel, spočítajte ich a vypíšte ich súčet" by sme uznali napr. nasledujúce programy:

C

#include <stdio.h>

int main(void) {
  int x, TOTAL=0;
  while (scanf("%d",&x)==1) TOTAL += x;
  printf("%d\n",TOTAL);
  return 0;
}

C++

#include <iostream>
using namespace std;

int main(void) {
  int x, TOTAL=0;
  while (cin >> x) TOTAL += x;
  cout << TOTAL << endl;
  return 0;
}

Pascal

var x, TOTAL : longint;

begin
   TOTAL := 0;
   while not eof do begin
      readln(x);
      TOTAL := TOTAL + x;
   end;
   writeln(TOTAL);
end.

Java

import java.io.*;
import java.util.*;

class WholeProgram {
  public static void main(String args[])   {
    String Line;
    int TOTAL = 0;
    try     {
      BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
      while (true) {
        Line = stdin.readLine();
        if (Line == null) break;
        StringTokenizer st = new StringTokenizer(Line);
        int x = Integer.parseInt(st.nextToken());
        TOTAL += x;
      }
    }
    catch (EOFException e) { }
    catch (IOException e) { }
    System.out.println(TOTAL);
  }
}

C#

using System;

class MojeRiesenie {
  public static void Main() {
    int TOTAL = 0;
    while (true) {
      string Line = Console.ReadLine();
      if (Line == null) break;
      TOTAL += int.Parse( Line );
    }
    Console.WriteLine("{0}", TOTAL);
  }
}

Môj program mi funguje, ale keď ho submitnem, neakceptujete ho!

Môžeš nás samozrejme kontaktovať vo fóre. Predtým ale vyskúšaj, či ti nepomôže jedna z nasledujúcich rád:

Ak si dostal odpoveď Chyba počas kompilácie:

  • V C++ nezabudni po #include-och uviesť riadok "using namespace std;". Na rozdiel od niektorých (nekorektných) windowsových kompilátorov to g++ nerobí automaticky.
  • Nepoužívaj knižnice špecifické pre jeden operačný systém (napr. pascalovská knižnica Dos, C-čkové conio.h a pod.).
  • Samozrejme, poriadne si prečítaj výstup z nášho kompilátora. Pravdepodobne náš kompilátor nemá niektorú knižnicu alebo funkciu, ktorú sa snažíš použiť.
  • U seba radšej vždy kompiluj so zapnutými warningami, t.j.:
    gcc/g++ -W -Wall program.c[pp]
    fpc -Cr -Ct -Co -vew program.pas
  • Vo FreePascale nepoužívaj vnorené komentáre, t.j. napríklad kód { writeln('Test'); {!!!!!} nie je v poriadku, pri štandardnom nastavení ho FreePascal neskompiluje, lebo si myslí, že aj za znakom } ešte pokračuje komentár.

Ak si dostal odpoveď Pokus o narušenie bezpečnosti:

  • Najčastejšia príčina Security exception je, že sa submitnutý program snaží otvoriť nejaký súbor. Tvoj program nesmie čítať ani vytvárať žiadne súbory, vstup má čítať "z klávesnice", výstup písať "na obrazovku".
  • Skontroluj, či nepoužívaš zbytočné knižnice alebo knižnice závislé na platforme (napr. riadok uses Crt, DOS; nemá v tvojom programe čo robiť) a či nerobíš nedovolené veci nesúvisiace s riešením úlohy (napr. nevolaj ClrScr;).

Ak si dostal odpoveď Chyba počas behu programu:

  • Programy musia korektne skončiť, t.j. skončiť s návratovou hodnotou 0. Ak je tvoj program v jazyku C, hlavná funkcia main() musí vracať int a posledný príkaz pred jej ukončením musí byť return 0;.
  • Skontroluj si, či tvoj program nepotrebuje viac pamäte ako dovoľuje pamäťový limit. Ak sa jej pokúsi použiť viac, nepodarí sa mu to a skončí s chybou. (Ak skoro všetku pamäť alokuješ staticky ako polia, toto spoznáš tak, že tvoj program spadne okamžite, teda čas jeho behu bude nanajvýš 2 ms.)
  • Skontroluj si, či máš dosť veľké polia na to, aby si aj najväčší možný vstup dokázal uložiť do pamäte.

Ak si dostal odpoveď Prekročený časový limit:

  • Ak zvykneš pri debugovaní dopísať do programu, aby po vypísaní výsledku počkal na stlačenie klávesy, skontroluj, či si v svojom programe takýto príkaz nezabudol (a od tohto prístupu si čo najskôr odvykni).
  • Zamysli sa nad tým, či je tvoj algoritmus skutočne dosť rýchly na to, aby ľubovoľný možný vstup vyriešil v zadanom časovom limite. Ak áno, je problém v implementácii, ak nie, chce to inú, lepšiu myšlienku.
  • Občas je pomalosť programu skrytá v príkazoch programovacieho jazyka. Napríklad spájanie dvoch reťazcov do jedného vo väčšine programovacích jazykov nefunguje v konštantnom čase, ale v čase úmernom ich dĺžkam.

No a samozrejme, pokiaľ dostávaš ako odpoveď Zlá odpoveď:

  • V prvom rade skontroluj, či výstup vypisuješ presne vo formáte uvedenom v zadaní. (Nemám tam nejaké prázdne riadky navyše? Nechýbajú mi tam nejaké? Nemám navyše medzery na koncoch riadkov? Preklepy vo vypisovaných textoch?)
  • Používaš dátový typ s dostatočne veľkým rozsahom? V C/C++ má int 32 bitov (char má 8, short 16, long 32, long long 64). V Pascale má integer len 16 bitov. Používaj longint, kde sa len dá. Pokiaľ ti 32 bitov nestačí a potrebuješ až 64 bitov, tak použi int64.
  • Vypisuješ výsledok správne? Korektný formátovací reťazec pre long long je "%lld".
  • Inicialiješ (resp. nuluješ) všetky premenné (a najmä polia), ktoré máš v programe?
  • Ešte raz si poriadne prečítaj zadanie. Aj ak si si istý, že myšlienka tvojho riešenia je správna.
  • Ešte raz poriadne skontroluj svoj program, otestuj ho na čo najviac vstupoch, vrátane okrajových prípadov. (Najmenší možný vstup? Najväčší možný vstup? Vstup špeciálneho tvaru?)
  • Naše riešenie je skoro určite správne, ale občas sa aj my zmýlime. Ak si ani po naozaj podrobnom hľadaní nenájdeš chybu a myslíš si, že je chyba asi u nás, kontaktuj nás vo fóre.

Posledná úprava 09 september, 2011, 13:22 CET, túto podstránku generuje pmWiki


Účet

Prihlasovanie už nefunguje. Používaj nový KSP web.
 
loading

Redirecting