Cod sursa(job #1684696)

Utilizator BugirosRobert Bugiros Data 11 aprilie 2016 11:27:03
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <fstream>
#include <algorithm>
#include <cstring>
using namespace std;

ifstream in("matrice2.in");
ofstream out("matrice2.out");

const int MAXN = 305;
const int MAXQ = 20005;

struct intrebare_binar
{
    int nr;
    int id;
};

bool ordine_buna_2(intrebare_binar a, intrebare_binar b)
{
    return a.nr > b.nr;
}

struct nod
{
    int x,y;
    int h;
};

bool ordine_buna_1(nod a, nod b)
{
    return a.h > b.h;
}

int n,q;
int nn;

bool in_interior(int x, int y)
{
    return (1 <= x && x <= n && 1 <= y && y <= n);
}


//atentie, pe infoarena y1 este deja declarat cu litere mici si
//da eroare de compilare
int X1[MAXQ], Y1[MAXQ], X2[MAXQ], Y2[MAXQ];

nod v[MAXN * MAXN];

int id[MAXN][MAXN];

int rasp[MAXQ];


void citire()
{
    in >> n >> q;
    for (int i = 1;i <= n;++i)
        for (int j = 1;j <= n;++j)
        {
            ++nn;
            id[i][j] = nn;
            v[nn].x = i;
            v[nn].y = j;
            in >> v[nn].h;
        }

    for (int i = 1;i <= q;++i)
        in >> X1[i] >> Y1[i] >> X2[i] >> Y2[i];
}

int tata[MAXN * MAXN];

int radacina(int x)
{
    if (x != tata[x])
        tata[x] = radacina(tata[x]);
    return tata[x];
}

bool vizitat[MAXN][MAXN];

void cautare_binara()
{
    int pas;
    for (pas = 1;pas < v[1].h;pas <<= 1);

    intrebare_binar intrebare[MAXQ];

    while(pas > 0)
    {
        for (int i = 1;i <= q;++i)
        {
            intrebare[i].nr = rasp[i] + pas;
            intrebare[i].id = i;
        }

        sort(intrebare + 1, intrebare + q + 1, ordine_buna_2);

        for (int i = 1;i <= nn;++i)
            tata[i] = i;

        memset(vizitat,0,sizeof(vizitat));

        int j;

        int dx[4] = {-1, 1, 0, 0};
        int dy[4] = {0, 0, -1, 1};
        j = 1;
        for (int i = 1;i <= nn;)
        {
            while (j <= q && intrebare[j].nr > v[i].h)
            {
                int nod1 = id[X1[intrebare[j].id]][Y1[intrebare[j].id]];
                int nod2 = id[X2[intrebare[j].id]][Y2[intrebare[j].id]];
                if (radacina(nod1) == radacina(nod2))
                    rasp[intrebare[j].id] += pas;
                ++j;
            }

            for (int k = i;i <= nn && v[i].h == v[k].h;++i)
            {
                vizitat[v[i].x][v[i].y] = true;
                for (int dir = 0;dir < 4;++dir)
                {
                    int xx = v[i].x + dx[dir];
                    int yy = v[i].y + dy[dir];
                    if (in_interior(xx,yy) && vizitat[xx][yy])
                        tata[ tata[ radacina(id[xx][yy]) ] ] = tata[ id[v[i].x][v[i].y] ];
                }
            }
        }

        while(j <= q)
        {
            int nod1 = id[X1[intrebare[j].id]][Y1[intrebare[j].id]];
            int nod2 = id[X2[intrebare[j].id]][Y2[intrebare[j].id]];

            if (radacina(nod1) == radacina(nod2))
                rasp[intrebare[j].id] += pas;

            ++j;
        }

        pas >>= 1;
    }
}

int main()
{
    citire();
    sort(v + 1, v + nn + 1, ordine_buna_1);
    cautare_binara();
    for (int i = 1;i <= q;++i)
        out << rasp[i] << '\n';
    return 0;
}