2011-02-04 20 views
6

Im la codifica di un problema (--http di riferimento: //www.codechef.com/FEB11/problems/THREECLR/)Java termine problema superato problema

Il sotto è il mio codice

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


public class Main { 

static String ReadLn (int maxLg) // utility function to read from stdin 
    { 
     byte lin[] = new byte [maxLg]; 
     int lg = 0, car = -1; 
     String line = ""; 

     try 
     { 
      while (lg < maxLg) 
      { 
       car = System.in.read(); 
       if ((car < 0) || (car == '\n')) break; 
       lin [lg++] += car; 
      } 
     } 
     catch (IOException e) 
     { 
      return (null); 
     } 

     if ((car < 0) && (lg == 0)) return (null); // eof 
     return (new String (lin, 0, lg)); 
    } 

public static boolean iscontains(HashMap<Integer,HashSet<Integer>> resultmap,HashSet<Integer> b, int index) 
{ 
    boolean result=false; 
    for(Iterator<Integer> iter = b.iterator();iter.hasNext();) 
     { int tmp=Integer.valueOf(iter.next().toString()); 
      if(resultmap.get(index).contains(tmp)) 
        result=true;     
     } 

    return result; 
} 


public static void main(String[] args) throws InterruptedException, FileNotFoundException { 
    try { 

    HashMap<Integer,HashSet<Integer>> pairlist = new HashMap<Integer,HashSet<Integer>>(); 
    String input=null; 
    StringTokenizer idata; 
    int tc=0; 
    input=Main.ReadLn(255); 
    tc=Integer.parseInt(input); 
    while(--tc>=0) 
    { 
     input=Main.ReadLn(255); 
     idata = new StringTokenizer (input);idata = new StringTokenizer (input); 
     int dishnum= Integer.parseInt(idata.nextToken()); 
     int pairnum= Integer.parseInt(idata.nextToken()); 
     while (--pairnum>=0) 
     { 
      input=Main.ReadLn(255); 
      idata = new StringTokenizer (input);idata = new StringTokenizer (input); 
      int dish1=Integer.parseInt(idata.nextToken()); 
      int dish2=Integer.parseInt(idata.nextToken()); 
      if(pairlist.containsKey((Integer)dish1)) 
      { 
       HashSet<Integer> dishes=new HashSet<Integer>(); 
       dishes=pairlist.get(dish1); 
       dishes.add(dish2); 
       pairlist.put(dish1, dishes); 
      } 
      else 
      { 
       HashSet<Integer> dishes=new HashSet<Integer>(); 
       dishes.add(dish2); 
       pairlist.put(dish1, dishes); 
      } 
     } 
     int maxrounds=1; 
     HashMap<Integer,HashSet<Integer>> resultlist = new HashMap<Integer,HashSet<Integer>>(); 
     HashSet<Integer> addresult=new HashSet<Integer>(); 
     addresult.add(1); 
     resultlist.put(1,addresult); 
     System.out.print("1"); 
     for(int i=2;i<=dishnum;i++) 
     { 
      boolean found_one=false; 
      boolean second_check=false; 
      int minroundnum=maxrounds; 
      boolean pairlistcontains=false; 
      pairlistcontains=pairlist.containsKey(i); 
      for(int j=maxrounds;j>=1;j--) 
      { 
       if(!found_one){ 
       if(pairlistcontains) 
       { 
        if(!iscontains(resultlist,pairlist.get((Integer) i),j)) 
        { 
         for(Iterator<Integer> resultiter = resultlist.get(j).iterator();resultiter.hasNext();) 
         { 
          if(pairlist.get(resultiter.next()).contains(i)) 
           second_check=true; 
         } 
         if(second_check==false) 
         { 
          found_one=true; 
          minroundnum=j; 
          j=0; 
          //second_check=false; 
         } 
        } 

       } 
       else 
       { 
        for(Iterator<Integer> resultiter = resultlist.get(j).iterator();resultiter.hasNext();) 
        { 
         if(pairlist.get(resultiter.next()).contains(i)) 
          second_check=true; 
        } 
        if(second_check==false) 
        { 
         found_one=true; 
         minroundnum=j; 
         j=0; 
         //second_check=false; 
        } 

       } 
       second_check=false; 


      } 
     } 
      if((minroundnum==maxrounds)&&(found_one==false)) 
       { 
       ++minroundnum; 
       ++maxrounds; 
       } 
      else 
      { 
       found_one=false; 
      } 
      HashSet<Integer> add2list=new HashSet<Integer>(); 
      if(resultlist.containsKey(minroundnum)) 
      { 
       add2list=resultlist.get(minroundnum); 
       add2list.add(i); 
      } 
      else 
      { 
       add2list.add(i); 
      } 
      resultlist.put(minroundnum,add2list); 
      System.out.print(" "); 
      System.out.print(minroundnum); 


     } 
     if((tc !=-1)) 
      System.out.println(); 

    } 


    } 
    catch(Exception e){System.out.println(e.toString());} 
}} 

Ho controllato questo codice su giudici online come Ideone e ho ottenuto i risultati desiderati. Ma quando invio questo codice, ottengo un errore di limite di tempo superato. Ho testato questo codice su Ideone con un set di input sufficientemente ampio e il tempo necessario per l'esecuzione era inferiore a 1 secondo. Sembra avere un bug o una perdita di memoria che sembra aver prosciugato tutta la felicità della mia vita. Qualsiasi suggerimento/suggerimento sarebbe molto apprezzato.

Grazie

EDIT1 -

Grazie per le risposte ragazzi, ho eseguito il codice con l'ingresso generato dal seguente script python -

import random 
filename="input.txt" 
file=open(filename,'w') 
file.write("50") 
file.write("\n") 
for i in range(0,50): 
     file.write("500 10000") 
     file.write("\n") 
     for j in range(0,10000): 
       file.write(str(random.randrange(1,501))+" "+str(random.randrange(1,501))) 
       file.write("\n") 
file.close() 

E il mio codice ha preso un enorme 71052 millisecondi da eseguire sull'input fornito dallo script precedente. Ora devo ridurre al minimo il tempo di esecuzione a 8000 millisecondi. Sto lavorando per provare a sostituire HashMaps e HashSet come suggerito da rfeak e sto anche chiedendo se la memoizzazione potrebbe aiutare in questo scenario. Si prega di avvisare.

EDIT2 - La ricodifica del mio algo utilizzando gli array sembra aver funzionato. Solo se, di nuovo lo stesso codice in momenti diversi, la soluzione accettata e il limite di tempo sono superati: D Ho comunque un altro modo di utilizzare le hashmap per ottimizzare ulteriormente. Grazie del carico per l'aiuto ragazzi!

+3

hai considerato che stanno alimentando un input molto più grande e il tuo codice impiega troppo tempo per elaborarlo? –

+0

Sai quanto è grande il set di dati che stanno inviando? Riesci a ottenere quel set di dati? –

+0

La mia ipotesi è che ti aspetti un input che non accade o che ci sia un input che fa sì che il tuo programma entri in un loop infinito. –

risposta

7

Quanta memoria utilizza il programma quando si esegue localmente?

Se stanno eseguendo il programma Java senza memoria sufficiente, si potrebbe passare molto tempo a cercare di raccogliere i dati. Questo potrebbe distruggere la tua 1 volta.

Se è necessario risparmiare tempo e memoria (per essere determinato ...), ho 2 suggetions.

Sostituire con BitSet. Interfaccia simile, implementazione molto più veloce e utilizza molta meno memoria. Soprattutto con i numeri che vedo nel problema.

Sostituire Map<Integer,X> con un X[] - La chiave Integer può essere semplicemente un indice (primitivo) nell'array. Di nuovo, più veloce e più piccolo.

+0

Definitivamente sbarazzarsi di 'HashSet' e' Mappa'. I numeri dati nel problema sono tutti abbastanza piccoli per un array (o 'BitSet' potrebbe essere anche più veloce di quello, ma non credo che ne hai bisogno qui) per essere abbastanza. – IVlad

+0

Grazie per il suggerimento. Non sono molto chiaro sull'implementazione di BitSet. JavaDoc dice che contengono la rappresentazione bit di un numero e supportano operazioni logiche su di essi. Non vorrei principalmente fare questo tipo di manipolazione sui dati di input, ma sicuramente proverei a farlo se è l'approccio più pratico e migliore. Si prega di avvisare. – Jcoder

+0

@JCoder - Ignora come descrive la sua rappresentazione interna. È meglio pensare a un BitSet come un insieme di int (primitivi). L'insieme contiene un numero intero oppure no. Per vedere se funziona, chiama BitSet.get (someInt). Per inserire un intero nella chiamata impostata BitSet.set (someInt). In questo modo si comporta esattamente come un Set . ... Ora, se sei davvero interessato al motivo per cui è più piccolo di un Set , posso aggiungere alla mia risposta. – rfeak