Pagini recente » Cod sursa (job #3261784) | Cod sursa (job #454632) | Cod sursa (job #817644) | Cod sursa (job #2978698) | Cod sursa (job #430738)
Cod sursa(job #430738)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>
int N; //numarul de gutui din copac
int H; //inaltimea maxima la care ajunge Gigel
int U; //cu cat se ridica crengile copacului dupa culegerea unei gutui
int* height; //inaltimile
int* weight; //greutatile gutuilor
int** values;
int* nr_values;
int greutate_max; //greutatea maxima a gutuilor culese
//intoarce minimum valorilor
int min(int a, int b)
{
if(a < b) {
return a;
} else {
return b;
}
}
//citeste din fisier matricea de 0/1
void citeste(char* nume_fisier)
{
int i;
char line[512]; //retine o linie citita
FILE* in = fopen(nume_fisier,"r"); //deschide fisier
if(in == NULL) { //daca nu s-a putut deschide fisierul afiseaza eroare
printf("Fisierul de intrare nu a putut fi gasit\n");
exit(1);
}
fgets(line,512,in); //citeste prima linie
N = atoi((char*)strtok(line," ")); //retine numarul de gutui din copac
H = atoi((char*)strtok(NULL," ")); //retine inaltimea maxima la care ajunge Gigel
U = atoi((char*)strtok(NULL," ")); //retine cu cat se ridica crengile copacului dupa culegerea unei gutui
height = (int*)malloc(sizeof(int)*N); //aloca memorie pentru matrice
weight = (int*)malloc(sizeof(int)*N); //aloca memorie pentru matricea rezultat
values = (int**)malloc(sizeof(int*)*(H/U)+1);
nr_values = (int*)malloc(sizeof(int)*(H/U)+1);
for(i=0;i<=H;i+=U) {
int row = i/U;
nr_values[row] = 0;
}
for(i=0;i<N;i++) { //pentru fiecare linie
fgets(line,512,in); //citeste linia
height[i] = atoi((char*)strtok(line," "));
weight[i] = atoi((char*)strtok(NULL," "));
int row = H/U-(H-height[i])/U;
if(row > 0 && row < H/U+1) {
nr_values[row]++;
}
}
fclose(in); //inchide fisierul
}
//calculeaza valorile dorite (greutatea maxima a gutuilor culese)
void calculeaza()
{
int row,j,k;
for(row=0;row<H/U+1;row++) {
values[row] = (int*)malloc(sizeof(int)*(nr_values[row]+1));
nr_values[row] = 0;
}
for(j=0;j<N;j++) {
int row = H/U-(H-height[j])/U;
if(row > 0 && row < H/U+1) {
values[row][nr_values[row]++] = j;
}
}
for(row=0;row < H/U+1;row++) {
int nr = nr_values[row];
for(j=0;j<nr-1;j++) {
for(k=j+1;k<nr;k++) {
if(weight[values[row][j]] < weight[values[row][k]]) {
int aux = values[row][j];
values[row][j] = values[row][k];
values[row][k] = aux;
}
}
}
}
for(row=0;row < H/U+1;row++) {
nr_values[row] = min(nr_values[row],H/U-row+1);
}
for(row=H/U;row>0;row--) {
int nr1 = nr_values[row];
int nr2 = nr_values[row-1];
int size = H/U-row + 2;
if(H%U != 0) {
size++;
}
int* new_values = (int*)malloc(sizeof(int)*size);
int p1 = 0,p2 = 0,p = 0;
for(j=0;j<min(nr1+nr2,size);j++) {
if(p1 == nr1) {
if(p2 != nr2) {
new_values[p++] = values[row-1][p2++];
} else {
break;
}
} else {
if(p2 == nr2) {
new_values[p++] = values[row][p1++];
} else {
if(weight[values[row][p1]] < weight[values[row-1][p2]]) {
new_values[p++] = values[row-1][p2++];
} else {
new_values[p++] = values[row][p1++];
}
}
}
}
if(p > nr_values[row-1]) {
free(values[row-1]);
values[row-1] = malloc(sizeof(int)*(p+1));
}
nr_values[row-1] = p;
for(j=0;j<p;j++) {
values[row-1][j] = new_values[j];
}
free(new_values);
free(values[row]);
}
for(j=0;j<nr_values[0];j++) {
greutate_max += weight[values[0][j]];
}
}
//scrie rezultatele in fisierul de iesire
void scrie(char* nume_fisier)
{
FILE* out = fopen(nume_fisier,"w"); //deschide fisier
fprintf(out,"%i",greutate_max); //scrie greutatea maxima
fclose(out); //inchide fisier
}
int main(int argc,char** argv)
{
citeste("gutui.in"); //citeste matricea din fisier
calculeaza(); //calculeaza valorile dorite
scrie("gutui.out"); //scrie rezultatele in fisier
return 0;
}