Cod sursa(job #440451)

Utilizator chocapicSima Ana chocapic Data 12 aprilie 2010 01:16:18
Problema Gutui Scor 0
Compilator c Status done
Runda teme_upb Marime 4.49 kb
#include<stdio.h>
#include<stdlib.h>
//#include<conio.h>

typedef struct gutui{
        int g;
        int h;
}gutui;


void citire(FILE *f,gutui *a,int n){   //citire vector de structuri din fisier
     int i;
     int aux;
     for(i=0;i<n;i++){    
          fscanf(f,"%d",&a[i].h);
          fscanf(f,"%d",&a[i].g);
          }
}
int comparare(const void *a,const void *b){  //functia de comparare folosita pentru sortarea descrescatoare a vectorului de structuri in ordinea inaltimilor
    gutui *a1,*b1;
    a1=(gutui*)a;
    b1=(gutui*)b;
    float rez1,rez2;
   return (*b1).h-(*a1).h;
}

float minim(gutui *v,int n,int *gr,int *poz){  //returneaza minimul din vector
    int i;
    float min=(float)v[0].g/v[0].h;
    for(i=0;i<n;i++){
                     if( ( (float)v[i].g/v[i].h ) < min){
                         min=(float)v[i].g/v[i].h;
                         (*poz)=i;                //pozitia elementului minim 
                         (*gr)=v[i].g;            //greutatea elementului minim
                        }//if  
                     }//for                       
    return min;
}

int nivel(int h,int hmax,int u){
    if(h < hmax)   return h/u;  //daca inaltimea nu depaseste inaltimea maxima, intoarce nivelul
    return -1;                  //altfel, intoarce -1 (depasire)
}

int greutate(gutui *v,int n,int hmax,int u){       //parcurge vectorul ordonat (dupa inaltimi) de structuri v pentru a gasi greutatea maxima 
    gutui *r=(gutui*)calloc(n,sizeof(gutui));      //vector care pastreaza structurile cu valorile cele mai bune pentru raportul greutate/inaltime
    int i,j=0;
    int gr=0;
    int poz=0;
    int gmax = v[0].g;
    int nc=nivel(v[0].h,hmax,u); //nivelul cel mai de sus
    printf("asta e nivelul %d\n",nc);
    r[0]=v[0];            //adauga primul element in vector
    i=1;
    j=1;
    while(i < n)  {               //pentru fiecare gutuie
      while( nivel((v[i].h+j*u),hmax,u) == nc){     //adauga in vector gutuile accesibile de pe nivelul curent
      printf("asta e nivelul %d\n",nc);
      //getch();
        r[j].g=v[i].g;
        r[j].h=(v[i].h+j*u);       //la pasul j, inaltimea tuturor gutuilor este cu j*u mai mare decat cea initiala
        gmax += v[i].g;
        i++;
        j++;
        }
      if(i>=n) break;
      if(nivel((v[i].h+j*u),hmax,u)!=-1) {       //nu exista gutui care sa fi devenit inaccesibile pe nivelul analizat, treci la nivelul urmator ( h nu a devenit mai mare decat hmax )
         nc=nivel((v[i].h+j*u),hmax,u);
         printf("nu s-a depasit hmax!\n");
         //getch();
         }
      else{
           while(nivel((v[i].h+j*u),hmax,u) == -1){         //restul de gutui de pe nivel au devenit inaccesibile (h > hmax), dar pot fi o alegere mai buna
              if(i>=n) break;
              if( (float)v[i].g/ (v[i].h+j*u) > minim(r,j,&gr,&poz) ) {  //elementul curent este mai bun decat cel mai prost element din vector
                  printf("s-a intrat in zona asta\n");// getch();
                    gmax -= gr;
                    gmax += v[i].g;
                    r[poz].g= v[i].g;
                    r[poz].h=(v[i].h+j*u); //inlocuieste si in vector minimul cu noua valoare
                    j++;
                    }//if
                i++;                
             }//while
        }//else     
    }//while 
      return gmax;
}

void scriere(FILE *f,gutui *a,int n){   //scriere vector de structuri din fisier
     int i;
     int aux;
     for(i=0;i<n;i++){    
          fprintf(f,"inaltimea:");
          fprintf(f,"%d",a[i].h);
          fprintf(f," ");   //write spatiu
          fprintf(f,"greutatea:");
          fprintf(f,"%d",a[i].g);
          fprintf(f,"\n");   //write newline
          }
}


int main(){
    gutui *v;    
    int gmax;
    int aux,hmax,u;
    int n;
    FILE *f,*g;
    f=fopen("gutui.in","rt");
    g=fopen("gutui.out","wt");
    fscanf(f,"%d",&n);          //citire numar gutui
    fscanf(f,"%d",&hmax);       //citire inaltime maxima
    fscanf(f,"%d",&u);          //citire inaltime cu care se ridica crengile la fiecare gutuie culeasa;
    v=(gutui*)malloc(n*sizeof(gutui));  //alocare memorie pentru vectorul de structuri
    citire(f,v,n);              //citire perechi gutuie-inaltime din fisier
   // scriere(g,v,n);
    fprintf(g,"\n\n");
    qsort(v,n,sizeof(gutui),comparare);
    gmax=greutate(v,n,hmax,u);
    printf("%d",gmax);
   // getch();
    //scriere(g,v,n);
    fclose(f);
    fclose(g);
}