Cod sursa(job #1831799)

Utilizator tudi98Cozma Tudor tudi98 Data 18 decembrie 2016 19:36:57
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <fstream>
#include <algorithm>
using namespace std;

int N,Q;
int a[301][301];
int X[20001];
const int dl[] = {0,0,-1,1};
const int dc[] = {1,-1,0,0};

struct Query {
	int x1,x2,y1,y2;
	int id;
	Query() {}
	Query(int _id,int _x1,int _y1,int _x2,int _y2) {
		id = _id;
		x1 = _x1;
		y1 = _y1;
		x2 =_x2;
		y2 = _y2;
	}
};

bool compQuery(Query a,Query b)
{
    return X[a.id] < X[b.id];
}

struct Coord {
	int x,y;
	Coord() {}
	Coord(int _x,int _y) {
		x = _x;
		y = _y;
	}
};


bool compCoord(Coord A,Coord B)
{
    return a[A.x][A.y] < a[B.x][B.y];
}

Query q[20001];
Coord c[300*300+1];

int P[301][301],h[301][301];

inline int xcoord(int n) {
	return n / 1000;
}

inline int ycoord(int n) {
	return n % 1000;
}

int root(int x,int y) {
	return (P[x][y] == x*1000+y) ? P[x][y] : (P[x][y] = root(xcoord(P[x][y]),ycoord(P[x][y])));
}

void unite(int x1,int y1,int x2,int y2) {
	int r1 = root(x1,y1);
	int r2 = root(x2,y2);
	x1 = xcoord(r1);
	x2 = xcoord(r2);
	y1 = ycoord(r1);
	y2 = ycoord(r2);
	if (h[x1][y1] > h[x2][y2])
		h[x1][y1] += h[x2][y2],
		P[x2][y2] = x1*1000+y1;
	else
		h[x2][y2] += h[x1][y1],
		P[x1][y1] = x2*1000+y2;
}

int main()
{
	ifstream fin("matrice2.in");
	ofstream fout("matrice2.out");

	fin >> N >> Q;
	for (int i = 1; i <= N; i++)
		for (int j = 1; j <= N; j++)
			fin >> a[i][j];

	for (int i = 1; i <= Q; i++) {
		int x1,x2,y1,y2;
		fin >> x1 >> y1 >> x2 >> y2;
		q[i] = Query(i,x1,y1,x2,y2);
	}

	int cn = 0;
	for (int i = 1; i <= N; i++)
		for (int j = 1; j <= N; j++)
			c[++cn] = Coord(i,j);

    fill_n(X+1,Q,0);
	sort(c+1,c+cn+1,compCoord);
	reverse(c+1,c+cn+1);

	int step = 1<<19;
    for (;step; step /= 2)
    {
        sort(q+1,q+Q+1,compQuery);
        reverse(q+1,q+Q+1);
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++) {
                h[i][j] = 1;
                P[i][j] = i * 1000 + j;
            }

        int at = 1;
        for (int i = 1; i <= Q; i++) {
            int lim = X[q[i].id] + step;
            for (; at <= cn && a[c[at].x][c[at].y] >= lim; at++) {
                for (int k = 0; k < 4; k++) {
                    int nx = c[at].x + dl[k];
                    int ny = c[at].y + dc[k];
                    if (nx > 0 && nx <= N && ny > 0 && ny <= N && a[nx][ny] >= lim && root(nx,ny) != root(c[at].x,c[at].y))
                        unite(nx,ny,c[at].x,c[at].y);
                }
            }
            if (root(q[i].x1,q[i].y1) == root(q[i].x2,q[i].y2))
                X[q[i].id] += step;
        }
    }

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