Cod sursa(job #463380)

Utilizator ssergiussSergiu-Ioan Ungur ssergiuss Data 15 iunie 2010 15:46:05
Problema Matrice 2 Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.24 kb
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
#include <fstream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef bool int01;
typedef char cha08;
typedef short int int16;
typedef int int32;
typedef float rea32;
typedef long long int int64;
typedef double rea64;

const cha08 Input[] = "matrice2.in";
const cha08 Output[] = "matrice2.out";

const int32 MaxN = 301;
const int32 MaxQ = 20001;

const int32 dx[] = {-1, 1, 0, 0};
const int32 dy[] = {0, 0, -1, 1};

int01 f[MaxN][MaxN];
int32 N, Q, K;
int32 r[MaxN * MaxN], t[MaxN * MaxN], ans[MaxQ], ind[MaxN * MaxN], h[MaxN][MaxN];
pair < pair <int32, int32>, pair<int32, int32> > query[MaxQ];

inline int32 X( int32 ind ) {

    if( ind % N == 0 )
        return ind / N;

    return (ind / N) + 1;
}

inline int32 Y( int32 ind ) {

    if( ind % N == 0 )
        return N;

    return ind % N;
}

struct cmp {

    int01 operator()( const int32 &ind1, const int32 &ind2 ) {

        return h[X( ind1 )][Y( ind1 )] > h[X( ind2 )][Y( ind2 )];
    }
};

int01 OK( int32 x, int32 y ) {

    if( x < 1 || x > N )
        return 0;
    if( y < 1 || y > N )
        return 0;

    return 1;
}

int32 Find( int32 nod ) {

    if( nod != t[nod] )
        t[nod] = Find( t[nod] );

    return t[nod];
}

void Unite( int32 nod1, int32 nod2 ) {

    if( r[nod1] < r[nod2] )
        t[nod1] = nod2;
    else
        t[nod2] = nod1;
    if( r[nod1] == r[nod2] )
        ++r[nod1];
}

void Cupl( int32 ind ) {

    int32 i;

    f[X( ind )][Y( ind )] = true;
    for( i = 0; i < 4; ++i )
        if( OK( X( ind ) + dx[i], Y( ind ) + dy[i] ) && f[X( ind ) + dx[i]][Y( ind ) + dy[i]] == true )
            Unite( Find( ind ), Find( (X( ind ) + dx[i] - 1) * N + Y( ind ) + dy[i] ) );
}

int32 main() {

    ifstream fin( Input );
    ofstream fout( Output );

    int32 i, j;

    fin >> N >> Q;
    for( i = 1; i <= N; ++i )
        for( j = 1; j <= N; ++j )
            fin >> h[i][j];
    for( i = 1; i <= Q; ++i )
        fin >> query[i].first.first >> query[i].first.second >> query[i].second.first >> query[i].second.second;

    for( i = 1; i <= N; ++i )
        for( j = 1; j <= N; ++j ) {

            ++K;
            ind[K] = K;
        }
    sort( ind + 1, ind + K + 1, cmp() );

//    for( int32 i = 1; i <= K; ++i )
//        fout << h[X( ind[i] )][Y( ind[i] )] << " " << X( ind[i] ) << " " << Y( ind[i] ) << "\n";

    for( i = 1; i <= K; ++i )
        t[i] = i;

    for( i = 1; i <= K; ++i ) {

        Cupl( ind[i] );
        while( i < K && h[X( ind[i] )][Y( ind[i] )] == h[X( ind[i + 1] )][Y( ind[i + 1] )] ) {

            ++i;
            Cupl( ind[i] );
        }

        for( j = 1; j <= Q; ++j )
            if( !ans[j] && Find( (query[j].first.first - 1) * N + query[j].first.second ) == Find( (query[j].second.first - 1) * N + query[j].second.second ) )
                ans[j] = h[X( ind[i] )][Y( ind[i] )];
    }

    for( i = 1; i <= Q; ++i )
        fout << ans[i] << "\n";

    fin.close();
    fout.close();

    return 0;
}