Cod sursa(job #475868)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 8 august 2010 22:27:41
Problema Matrice 2 Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.95 kb
# include <stdio.h>
# include <vector>
# include <algorithm>
# include <map>

using namespace std;

#define MAXN 300
#define MAXQ 20000
#define COORD(i,j) (((i)-1)*n+(j))

long int a[MAXN+1][MAXN+1],n,q;

typedef struct REQUEST {long int x1,y1,x2,y2,sol;} REQUEST;
REQUEST req[MAXQ+1];

const long int vi[4] = {-1, 0, 1, 0};
const long int vj[4] = {0, 1, 0, -1};

map<long int, vector<long int> > reqNumbers;

typedef struct MOUNTAIN {long int x,y,h;} MOUNTAIN;

MOUNTAIN mountains[MAXN*MAXN+1];

long int multime[MAXN*MAXN+1];

vector<long int> merged;

long int getSet(long int coord){
     long int getcoord = coord;
     while (multime[getcoord] != getcoord){
           getcoord = multime[getcoord];
     }
     multime[coord] = getcoord;
     return getcoord;
}

void mergeSet(long int set1, long int set2, long int sol){
     if (set1 == set2){
        return;
     }
     multime[set1] = set2;
     //
     if (reqNumbers.find(set1) == reqNumbers.end()){
        return;
     }
     if (reqNumbers.find(set2) == reqNumbers.end()){
        reqNumbers[set2].swap(reqNumbers[set1]);
        return;
     }
     long int i = 0;
     long int j = 0;
     merged.clear();
     while (i < reqNumbers[set1].size() && j < reqNumbers[set2].size()){
           if (reqNumbers[set1][i] == reqNumbers[set2][j]){
              req[reqNumbers[set1][i]].sol = sol;
              i++;
              j++;
           } 
           else if (reqNumbers[set1][i] < reqNumbers[set2][j]){
              merged.push_back(reqNumbers[set1][i]);
              i++;
           } else {
              merged.push_back(reqNumbers[set2][j]);
              j++;
           }
     }
     while (i < reqNumbers[set1].size()){
           merged.push_back(reqNumbers[set1][i]);
           i++;
     }
     while (j < reqNumbers[set2].size()){
           merged.push_back(reqNumbers[set2][j]);
           j++;
     }
     reqNumbers[set2].swap(merged);
     reqNumbers.erase(set1);
}

void citire()
{
     FILE * f = fopen ("matrice2.in","r");
     fscanf(f,"%ld%ld",&n,&q);
     for (long int i = 1; i <= n; i++)
         for (long int j = 1; j <= n; j++){
             fscanf(f,"%ld",&a[i][j]);
         }
     for (long int i = 1; i <= q; i++){
         fscanf(f,"%ld%ld%ld%ld",&req[i].x1,&req[i].y1,&req[i].x2,&req[i].y2);
     }
     fclose(f);
}

bool compara(const MOUNTAIN& m1, const MOUNTAIN& m2)
{
     return m2.h<m1.h;
}

void calculeaza()
{
     //create the mountains
     for (long int i = 1; i <= n; i++)
         for (long int j = 1; j <= n; j++){
             mountains[COORD(i,j)].x = i;
             mountains[COORD(i,j)].y = j;
             mountains[COORD(i,j)].h = a[i][j];
             multime  [COORD(i,j)] = COORD(i,j);
         }
     //attaching requests
     for (long int i = 1; i <= q; i++){
         reqNumbers[COORD(req[i].x1,req[i].y1)].push_back(i);
         reqNumbers[COORD(req[i].x2,req[i].y2)].push_back(i);
     }
     //sorting by altitude
     sort(mountains+1,mountains+n*n+1,compara);
     //do the magic
     for (long int i = 1; i <= n*n; i++){
         //now checking mountains[i]. First, see if it has bigger newighbours
         for (long int dir = 0; dir < 4; dir++){
             long int nx = mountains[i].x + vi[dir];
             long int ny = mountains[i].y + vj[dir];
             if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && a[nx][ny] > mountains[i].h){
                //create a merge
                //printf("%ld %ld with %ld %ld\n",mountains[i].x,mountains[i].y,nx,ny);fflush(stdin);getchar();
                mergeSet(getSet(COORD(nx,ny)),getSet(COORD(mountains[i].x,mountains[i].y)), mountains[i].h);
             }
         }
     }
}

void scrie()
{
     FILE *g= fopen("matrice2.out","w");
     for (long int i = 1; i <= q; i++)
         fprintf(g,"%ld\n",req[i].sol);
     fclose(g);
}

int main()
{
    citire();
    calculeaza();
    scrie();
    return 0;
}