Cod sursa(job #475880)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 8 august 2010 23:01:25
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.99 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;

long int reqsol[MAXQ+1];

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

vector<long int>* reqNumbers[MAXN*MAXN+1];

typedef struct MOUNTAIN {long int x,y;} 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;
     //
     long int i = 0;
     long int j = 0;
     if (reqNumbers[set1] == NULL){
        return;
     }
     if (reqNumbers[set2] == NULL){
        reqNumbers[set2] = reqNumbers[set1];
        reqNumbers[set1] = NULL;
        return;
     }
     vector<long int>& reqn1 = *reqNumbers[set1];
     vector<long int>& reqn2 = *reqNumbers[set2];
     merged.clear();
     while (i < reqn1.size() && j < reqn2.size()){
           if (reqn1[i] == reqn2[j]){
              reqsol[reqn1[i]] = sol;
              i++;
              j++;
           } 
           else if (reqn1[i] < reqn2[j]){
              merged.push_back(reqn1[i]);
              i++;
           } else {
              merged.push_back(reqn2[j]);
              j++;
           }
     }
     while (i < reqn1.size()){
           merged.push_back(reqn1[i]);
           i++;
     }
     while (j < reqn2.size()){
           merged.push_back(reqn2[j]);
           j++;
     }
     reqn2.swap(merged);
     delete reqNumbers[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]);
         }
     long int x1,y1,x2,y2;
     for (long int i = 1; i <= q; i++){
         fscanf(f,"%ld%ld%ld%ld",&x1,&y1,&x2,&y2);
         if (reqNumbers[COORD(x1,y1)] == NULL){
            reqNumbers[COORD(x1,y1)] = new vector<long int>();
         }
         reqNumbers[COORD(x1,y1)]->push_back(i);
         if (reqNumbers[COORD(x2,y2)] == NULL){
            reqNumbers[COORD(x2,y2)] = new vector<long int>();
         }
         reqNumbers[COORD(x2,y2)]->push_back(i);
     }
     fclose(f);
}

bool compara(const MOUNTAIN& m1, const MOUNTAIN& m2)
{
     return a[m2.x][m2.y]<a[m1.x][m1.y];
}

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;
             multime  [COORD(i,j)] = COORD(i,j);
         }
     //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] > a[mountains[i].x][mountains[i].y]){
                //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)), a[mountains[i].x][mountains[i].y]);
             }
         }
     }
}

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

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