Cod sursa(job #2023550)

Utilizator mihai.alphamihai craciun mihai.alpha Data 19 septembrie 2017 09:17:35
Problema Matrice 2 Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.55 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

FILE *fin, *fout;

#define MAXN 300
#define MAXQ 20000
#define MAXN_2 90000
#define MAXVAL 1000000

int N, Q;
int a[MAXN + 1][MAXN + 1];
int x1[MAXQ + 1], Y1[MAXQ + 1], x2[MAXQ + 1], y2[MAXQ + 1];
int st[MAXQ + 1], dr[MAXQ + 1], viz[MAXN + 1][MAXN + 1];
std::vector <int> check[MAXVAL + 1];

struct at {
    int x, y;
    bool operator != (const at &a) const {
        if (a.x != x || a.y != y)
            return 1;
        return 0;
    }
    bool operator == (const at &a) const {
        if (a.x == x && a.y == y)
            return 1;
        return 0;
    }
};

struct util {
    int x, y, val;
};

util mat[(MAXN + 1) * (MAXN + 1) + 1];
int ind;

std::queue <at> q;

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

at parent[MAXN + 1][MAXN + 1];

inline void union1(at a, at b) {
    if (a.x == b.x && a.y == b.y)
        return;
    while (parent[a.x][a.y] != a)
        a = parent[a.x][a.y];
    while (parent[b.x][b.y] != b)
        b = parent[b.x][b.y];
    if (b.x == a.x && b.y == a.y)
        return;
    parent[b.x][b.y].x = a.x;
    parent[b.x][b.y].y = a.y;
}

inline at find(at a) {
    while (a != parent[a.x][a.y])
        a = parent[a.x][a.y];
    return a;
}

int nn;

inline void make(int limit) {
    int ind = 1, ind1 = 2;
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N; j++)
            parent[i][j] = { i, j };
    while (ind <= nn && mat[ind].val >= limit) {
        for (int j = 0; j < 3; j++) {
            int X = mat[ind].x + dx[j];
            int Y = mat[ind].y + dy[j];
            if (a[X][Y] >= limit) {
                union1({ mat[ind].x, mat[ind].y }, { X, Y });
            //  printf("%d %d  %d %d\n", find({ mat[ind].x, mat[ind].y }).x, find({ mat[ind].x, mat[ind].y }).y, find({ X, Y }).x, find({ X, Y }).y);
            }
        }
        ind++;
    }
}

bool cmp(util a, util b) {
    return a.val > b.val;
}

int main() {
    fin = fopen("matrice2.in", "r");
    fout = fopen("matrice2.out", "w");
    fscanf(fin, "%d%d", &N, &Q);
    nn = N * N;
    for(int i = 1;i <= N;i++)
        for (int j = 1; j <= N; j++) {
            fscanf(fin, "%d", &a[i][j]);
            mat[++ind].val = a[i][j];
            mat[ind].x = i;
            mat[ind].y = j;
        }
    std::sort(mat + 1, mat + ind + 1, cmp);
    for (int i = 1; i <= Q; i++) {
        fscanf(fin, "%d%d%d%d", &x1[i], &Y1[i], &x2[i], &y2[i]);
        st[i] = 1, dr[i] = MAXVAL;
    }
    bool ok = 1;
    int pana;
    while (ok) {
        ok = 0;
        pana = 0;
        for (int i = 1; i <= Q; i++) {
            if (st[i] != dr[i]) {
                check[(st[i] + dr[i]) / 2].push_back(i), pana = std::max(pana, (st[i] + dr[i]) / 2);
            //  printf("%d  %d %d\n", i, st[i], dr[i]);
            }
        }
        for (int i = 1; i <= pana; i++) {//iau fiecare pas al cautarii binare si pun limita i
            if(check[i].size())
                make(i);
            while (check[i].size()) {
                ok = 1;
                int who = check[i].back();//query-ul curent
                check[i].pop_back();
                bool ver = 0;
                if (find({ x1[who], Y1[who] }) == find({ x2[who], y2[who] }))
                    ver = 1;
                if (ver == 1) {
            //      printf("aa");
                    st[who] = i + 1;
                }
                else
                    dr[who] = i;
            }
        }
    }
    for (int i = 1; i <= Q; i++)
        fprintf(fout, "%d\n", st[i] - 1);
    fclose(fin);
    fclose(fout);
    return 0;
}