Cod sursa(job #575049)

Utilizator barosanulmarele bastan barosanul Data 7 aprilie 2011 20:39:42
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <algorithm>
#include <stdio.h>
#include <vector>

#define MAX 310
#define MAXQ 20010
#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

int dirX[] = {-1, 0, 0, 1};
int dirY[] = {0, -1, 1, 0};
int n, q;
int matAlt[MAX][MAX];
int xs[MAXQ], ys[MAXQ], xf[MAXQ], yf[MAXQ], sol[MAXQ];
pair <int, int> vctNr[MAX * MAX];
pair <int, int> t[MAX][MAX];
vector <int> vctQuery;

inline bool cmp(const pair <int, int> &a, const pair <int, int> &b)
{
	return matAlt[a.x][a.y] < matAlt[b.x][b.y];
}

inline pair <int, int> tata(pair <int, int> nod)
{
	if (t[nod.x][nod.y] != nod)
		t[nod.x][nod.y] = tata(t[nod.x][nod.y]);

	return t[nod.x][nod.y];
}

inline void test(int mx)
{
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			t[i][j] = mp(0, 0);

	for (int i = 1; i <= n * n; i++)
	{
		int x = vctNr[i].x, y = vctNr[i].y;
		if (matAlt[x][y] < mx)
			break;
		t[x][y] = mp(x, y);

		for (int dir = 0; dir < 4; dir++)
		{
			if (!(x + dirX[dir]) || (x + dirX[dir] > n) || !(y + dirY[dir]) || (y + dirY[dir] > n) || t[x + dirX[dir]][y + dirY[dir]] == mp(0, 0))
				continue;
			pair <int, int> p1 = tata(mp(x, y));
			pair <int, int> p2 = tata(mp(x + dirX[dir], y + dirY[dir]));
			
			if (p1 != p2)
				t[p1.x][p1.y] = tata(mp(p2.x, p2.y));
		}
	}
}

inline void cautaBin(int fr, int ls, vector <int> vctQuery)
{
	if (fr > ls)
		return;

	int med = (fr + ls) / 2;

	test(med);

	vector <int> vctm, vctM;
	for (int i = 0; i < vctQuery.size(); i++)
	{
		int l = vctQuery[i];

		if (t[xs[l]][ys[l]] != mp(0, 0) && t[xf[l]][yf[l]] != mp(0, 0) && tata(mp(xs[l], ys[l])) == tata(mp(xf[l], yf[l])))
		{
			sol[l] = med;

			vctM.pb(l);
		}
		else vctm.pb(l);
	}

	if (vctm.size())
		cautaBin(fr, med - 1, vctm);
	if (vctM.size())
		cautaBin(med + 1, ls, vctM);
}

int main()
{
	freopen("matrice2.in", "r", stdin);
	freopen("matrice2.out", "w", stdout);

	scanf("%d %d", &n, &q);

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
		{
			scanf("%d", &matAlt[i][j]);

			vctNr[(i - 1) * n + j] = mp(i, j);
		}

	sort(vctNr + 1, vctNr + 1 + n * n, cmp);
	reverse(vctNr + 1, vctNr + 1 + n * n);

	for (int i = 1; i <= q; i++)
	{
		scanf("%d %d %d %d", &xs[i], &ys[i], &xf[i], &yf[i]);

		vctQuery.pb(i);
	}
	
	cautaBin(1, 10, vctQuery);

	for (int i = 1; i <= q; i++)
		printf("%d\n", sol[i]);

	fclose(stdin);
	fclose(stdout);
	return 0;
}