최소, 최대 정사각형 찾기 2 질문입니다.

  • gon
    gon

    계속해서 TLE가 나고 있어 질문 올립니다.

    지금 제 방법은 임의의 2점을 잡고나서 나머지 2점은 이분검색으로 찾는데 시간복잡도는 2N^2logN입니다. N이 2만이므로 당연히 TLE가 나겠지만, 더 줄일 수 있는 방법을 몰라 이렇게 글을 올립니다.

    줄일 수 있는 방법이나 다른 획기적인 방안이 없을까요?

    // 밑에는 제 코드입니다.

    #include
    #include
    #define M_abs(X, Y) (X-Y) > 0 ? (X-Y) : (Y-X)
    using std::sort;

    struct XY{

    int x, y;

    };
    typedef struct XY xy;
    xy sq[20010];
    int sq_seq[20010][2];
    bool compare ( const xy &fi, const xy &se ){

    if( fi.x == se.x )
        return fi.y < se.y;
    return fi.x < se.x;

    }

    bool find_point( int p, int x, int y )
    {
    int fp = p - sq_seq[p][0];
    int rp = p + sq_seq[p][1];
    int mp;

    while( fp <= rp ){
    
        mp = (fp + rp) / 2;
        if( sq[mp].y == y )
            return true;
        else if( sq[mp].y > y ) 
            rp = mp-1;
        else
            fp = mp+1;
    }
    return false;

    }
    int main()
    {
    int T;
    int N, i, j;
    int length_X, length_Y;
    int max, min;
    freopen("input.txt","rt",stdin);
    freopen("output.txt","wt",stdout);

    scanf("%d", &T);
    while( T-- ){
    
        max = -1; min = 0x7fffffff;
        scanf("%d", &N);
        for( i=0;i<N;i++ ){
    
            scanf("%d %d", &sq[i].x, &sq[i].y);
        }
    
        sort( sq, sq+N, compare );
    
        /*for( i=0;i<N;i++ ){
    
            printf("%d ", sq[i].x);
        }
        printf("\n");*/
        sq_seq[0][0] = 0;
        sq_seq[N-1][1] = 0;
    
        for( i=1;i<N;i++ ){
    
            if( sq[i].x != sq[i-1].x )
                sq_seq[i][0] = 0;
            else
                sq_seq[i][0] = sq_seq[i-1][0] + 1;
    
            if( sq[N-i-1].x != sq[N-i].x )
                sq_seq[N-i-1][1] = 0;
            else
                sq_seq[N-i-1][1] = sq_seq[N-i][1] + 1;
        }
    
        /*printf("----------------sq_seq--------------\n");
        for( i=0;i<N;i++ ){
    
            printf("%d ",sq_seq[i][0] );
        }
        printf("\n");
        for( i=0;i<N;i++ ){
    
            printf("%d ",sq_seq[i][1]);
        }
        printf("\n");
        printf("----------------sq_seq_end----------\n");*/
    
        for( i=0;i<N;i++ ){
    
            for( j=i+1;j<N;j++ ){
    
                length_X = M_abs(sq[i].x, sq[j].x);
                length_Y = M_abs(sq[i].y, sq[j].y);
    
                if( length_X != length_Y ) continue;
                // sq[j].x AND sq[i].y 
                // sq[i].x AND sq[j].y;
    
                if( find_point( j, sq[j].x , sq[i].y ) && find_point( i, sq[i].x, sq[j].y ) ){
    
                    max = max < length_X ? length_X : max;
                    min = min > length_X ? length_X : min;
                }
            }
        }
        printf("%d %d\n",min,max);
    }
    
    return 0;

    }


    10년 전
4개의 댓글이 있습니다.
  • Kureyo
    Kureyo

    음 글쎼요..아무튼 find_point가 가장 비싼연산이니까 앞에서 length_X가 max보다도 작고 min보다도 크면 continue하는 식으로 하면 조금더 빨라지지 않을까요?ㅜㅜ


    10년 전 link
  • gon
    gon

    좋은 의견 감사합니다. ( TLE는 해결이 되지 않네요 ㅜㅜ )


    10년 전 link
  • Kureyo
    Kureyo

    음 몇가지 의견을 더 내보자면 또 j의 y값이 i의 y값보다 작을때는 고려 안해도 되지않을까요? ㅠㅠ 이렇게 생각하면 x-y값을 key값으로 해서 key값이 같은 애들끼리만 비교해본다거나할수도있을거같네요


    10년 전 link
  • gon
    gon

    의견 내주셔서 감사합니다. 음 한번 해볼만한 것 같습니다. ㅎㅎ


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