외판원 문제 뭐가 잘못된 건지.. -_-;;

  • jukrang
    jukrang

    import java.util.Scanner;

    public class Main {

    /*

    private double[] results = null;

    private double sumBuff;
    private double min = -1;

    public int inputCaseCnt() {
    int caseCnt = Integer.parseInt( this.scanner.nextLine() );
    return caseCnt;
    }

    public void start() {
    int caseCnt = this.inputCaseCnt();
    int n = 0;

    double      minDistance =   0;
    Scanner     tokeNizer   =   null;
    
    results     =   new double[ caseCnt ];
    
    for( int r = 0; r < caseCnt; r++ ) {
        n       =   Integer.parseInt( scanner.nextLine() );
        posMap  =   new double[ n ][ n ];
    
        for( int i = 0; i < n; i++ ) {
            tokeNizer   =   new Scanner( scanner.nextLine() );
    
            int j   =   0;
            while( tokeNizer.hasNext() ) {
                posMap[ i ][ j++ ]  =   Double.parseDouble( tokeNizer.next() );
            }
        }
    
        results[ r ]    =   this.getTheShortestDistance( n );
    }
    
    for( double d : results ) {
        System.out.format( "%.10f\n", d );
    }

    }

    private double getTheShortestDistance( int n ) {
    int[] combArray = null;
    int[] newCombArray = null;
    int checker = 0;

    int curIdx  =   0;
    for( int i = 0; i < n; i++ ) {
        this.sumBuff    =   0;
        checker     =   0;
        combArray   =   new int[ n ];
    
        checker =   checker | ( 1 << i );
        combArray[ curIdx ] =   ( i + 1 );
    
        newCombArray    =   this.combinate( checker, combArray, n, curIdx );
    
        /* 경로가 담겨 있는 조합의 최단 거리를 구함 */
        this.addMinDistance( newCombArray );
    
        /* 최소 값 구함 */
        if( this.min < 0 ) {
            this.min    =   this.sumBuff;
    
        } else if( this.min > this.sumBuff ) {
            this.min    =   this.sumBuff;
        }
    }
    /* 여기서 출력 */
    return this.min;

    }

    /*

    • int 배열 복사
      **/
      private int[] arrayCopy( final int[] srcArray ) {
      final int LEN = srcArray.length;

      int[] newArray = new int[ LEN ];
      for( int j = 0; j < LEN; j++ ) {
      newArray[ j ] = srcArray[ j ];
      }

      return newArray;
      }

    /*

    • 가능한 조합 추출
      **/
      private int[] combinate( int srcChecker, int[] combArray, int n, int curIdx ) {
      curIdx++;

      if( curIdx == n ) {
      return combArray;
      }

      int newChecker = 0;
      int[] newCombArray = null;

      newChecker = srcChecker;
      newCombArray = this.arrayCopy( combArray );

      for( int i = 0; i < n; i++ ) {
      /* 새로운 배열을 만들어서 이용하지 않으면 값이 참조가 되는 문제 발생 */
      if( ( ( newChecker & ( 1 << i ) ) ) > 0 ) {
      continue;
      }

      newCombArray[ curIdx++ ]    =   ( i + 1 );

      }

      return newCombArray;
      }

    public void addMinDistance( int[] combArray ) {
    int now = combArray[ 0 ] - 1;
    int next = combArray[ 1 ] - 1;

    /* 0번째부터 1번째까지의 거리 */
    double  min     =   Math.abs( this.posMap[ now ][ now ] - this.posMap[ now ][ next ] );
    
    if( combArray.length == 2 ) {
        /* 배열 원소가 2개이면 무조건 최단거리임 */
        this.sumBuff    +=  min;
        return;
    
    } else {
        /* 배열의 원소가 2개 이상이면 가장 짧은 거리를 더함 */
        double  temp    =   0;
        for( int i = 2; i < combArray.length; i++ ) {
            next    =   combArray[ i ] - 1;
            temp    =   Math.abs( this.posMap[ now ][ now ] - this.posMap[ now ][ next ] );
    
            if( min > temp ) {
                min =   temp;
            }
        }
        this.sumBuff    +=  min;
    }
    
    int[]   subsets =   new int[ combArray.length -  1 ];
    
    for( int i = 1; i < combArray.length; i++ ) {
        subsets[ i - 1 ]    =   combArray[ i ];
    }
    
    this.addMinDistance( subsets );

    }

    public static void main(String[] args) {
    new Main().start();
    }
    }

    위와 같이 풀었습니다.
    시간도 문제 없어 보이구요.

    정답도 잘 나오는데 왜 오답처리 되는지 알 수 있을까요?
    도무지 모르겠네요. -_-;;


    11년 전
5개의 댓글이 있습니다.
  • JongMan
    JongMan

    정답이 안나오니까 오답처리가 되겠죠? -_-;; 다음 입력을 돌려보세요.

    4
    3
    0.0000000000  611.6157225201  648.7500617289
    611.6157225201  0.0000000000  743.8557967501
    648.7500617289  743.8557967501  0.0000000000
    4
    0.0000000000  326.0008994586  503.1066076077  290.0250922998
    326.0008994586  0.0000000000  225.1785728436  395.4019367384
    503.1066076077  225.1785728436  0.0000000000  620.3945520632
    290.0250922998  395.4019367384  620.3945520632  0.0000000000
    3
    0.0000000000  611.6157225201  648.7500617289
    611.6157225201  0.0000000000  743.8557967501
    648.7500617289  743.8557967501  0.0000000000
    4
    0.0000000000  326.0008994586  503.1066076077  290.0250922998
    326.0008994586  0.0000000000  225.1785728436  395.4019367384
    503.1066076077  225.1785728436  0.0000000000  620.3945520632
    290.0250922998  395.4019367384  620.3945520632  0.0000000000

    11년 전 link
  • jukrang
    jukrang

    오홋. 감사합니다. 다듬어 볼게요~!


    11년 전 link
  • jukrang
    jukrang

    그래도 오답이네요. ㅠ
    음... 뭐가 문제인거지. 이 문제 때문에 아무 것도 할 수 없어. ㅠㅠ ㅋㅋ


    11년 전 link
  • Being
    Being

    위에서 아주 작은 테스트 케이스임에도 불구하고 오답을 내셨는데, 이런 경우는 랜덤한 데이터를 만들고 '무식하게 푼' 솔루션과 답을 비교해 보는 방식으로 충분히 확인할 수 있습니다. 그렇게 해서 작은 데이터에서는 틀리지 않는다고 확신이 드실 때 다시 질문해 보시는 게 어떨까요?


    11년 전 link
  • jukrang
    jukrang

    넵~ 그렇게 한 번 해볼게요. 조언 감사합니다.


    11년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.