2011-02-04 3 views
6

Im кодирования проблемы (ссылка --http: //www.codechef.com/FEB11/problems/THREECLR/)Java лимит времени проблема превысил выпуск

Ниже мой код

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());} 
}} 

Я проверил этот код на онлайн-судьях, таких как Ideone, и получил желаемые результаты. Но когда я отправляю этот код, я получаю превышен лимит времени. Я проверил этот код на Ideone с достаточно большим набором входных данных, и время, затраченное на выполнение, было менее 1 секунды. Кажется, у него есть ошибка или утечка памяти, которая, похоже, истощила все счастье от моей жизни. Любые указатели/советы были бы весьма признательны.

Благодаря

EDIT1 -

Спасибо за ответы, ребята, я побежал код с входом генерируемого следующим питоном сценария -

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() 

И мой код взял колоссальный 71052 миллисекунды для выполнения на входе, предоставленном вышеупомянутым скриптом. Теперь я должен сократить время выполнения до 8000 миллисекунд. Im работает над попытками заменить HashMaps и HashSets, как это было предложено rfeak, и мне также интересно, поможет ли memoization в этом сценарии. Пожалуйста, порекомендуйте.

EDIT2 - Перекодирование моего алгоритма с использованием массивов, похоже, сработало. Только только при повторном повторении одного и того же кода в разное время я получил допустимое решение и предел времени: D У меня есть другой способ использовать хэш-карты для оптимизации немного дальше. Спасибо за помощь, ребята!

+3

Вы считаете, что они подают его гораздо больший ввод, и ваш код занимает слишком много времени, чтобы обработать его? –

+0

Знаете ли вы, насколько большой набор данных, который они представляют? Можете ли вы получить этот набор данных? –

+0

Я предполагаю, что вы ожидаете ввода, которого не происходит, или есть вход, который заставляет вашу программу перейти в бесконечный цикл. –

ответ

7

Сколько памяти ваша программа используется при запуске локально?

Если они запускают вашу программу Java без достаточной памяти, вы можете потратить много времени на сбор мусора. Это может уничтожить ваш 1 второй раз.

Если вам нужно сэкономить время и память (будет определено ...), у меня есть 2 предложения.

Заменить на BitSet. Подобный интерфейс, намного более быстрая реализация, и использует гораздо меньше памяти. Особенно с цифрами, которые я вижу в проблеме.

Замените Map<Integer,X> на X[]. Ключ Integer может быть просто индексом int (примитивный) в ваш массив. Опять же, все быстрее и меньше.

+0

Определенно избавиться от 'HashSet' и' Map'. Номера, заданные в задаче, достаточно малы для массива (или «BitSet» может быть даже быстрее, чем это, но я не думаю, что вам это нужно), чтобы быть достаточно. – IVlad

+0

Спасибо за предложение. Я не очень четко понимаю реализацию BitSet. JavaDoc говорит, что они содержат представление бит числа и поддерживают логические операции над ними. Вначале я бы не хотел делать такие манипуляции с входными данными, но определенно попытался бы это сделать, если это самый практичный и лучший подход. Пожалуйста, порекомендуйте. – Jcoder

+0

@JCoder - Игнорировать, как он описывает внутреннее представление. Лучше подумать о BitSet как о наборе int (примитивов). В наборе либо содержится целое число, либо нет. Чтобы узнать, действительно ли это, вызовите BitSet.get (someInt). Чтобы поместить целое число в заданный вызов BitSet.set (someInt). Таким образом, он ведет себя точно как Set . ... Теперь, если вас действительно интересует, почему он меньше, чем Set , я могу добавить к моему ответу. – rfeak

Смежные вопросы