Pagini recente » Cod sursa (job #1592067) | Cod sursa (job #436142) | Cod sursa (job #3271572) | Cod sursa (job #3295301) | Cod sursa (job #3300916)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#define MAX 120001
typedef struct
{
float x, y;
}Coord;
long int N, stanga = 0;
Coord puncte[MAX], infasuratoare[MAX];
typedef Coord Element_t;
typedef struct
{
Element_t st[MAX];
size_t cap;
size_t vf;
}Stack_t;
Stack_t stack;
typedef enum ErrorCode
{
PUSH_OK, STACK_EMPTY, STACK_FULL
}EC_t;
void interpretare_eroare(EC_t eroare)
{
switch(eroare)
{
case 0:
{
printf("Elementul a ajuns in stiva cu succes!\n");
break;
}
case 1:
{
printf("Stiva este goala!\n");
break;
}
case 2:
{
printf("Stiva este plina!\n");
break;
}
default:
break;
}
eroare = 3;
}
void push(Stack_t *stiva, Element_t nou)
{
if(stiva->vf == stiva->cap - 1)
{
EC_t eroare = STACK_FULL;
interpretare_eroare(eroare);
return;
}
else
{
(stiva->vf)++;
stiva->st[stiva->vf] = nou;
}
}
Element_t pop(Stack_t *stiva)
{
Element_t data;
if(stiva->vf == -1)
{
EC_t eroare = STACK_EMPTY;
interpretare_eroare(eroare);
return (Coord){0, 0};
}
else
{
data = stiva->st[stiva->vf];
(stiva->vf)--;
return data;
}
}
float cross(Coord p1, Coord p2, Coord p3)
{
return (p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x);
}
int compare(const void* p1, const void* p2)
{
float val = cross(puncte[0], *(Coord*)p1, *(Coord*)p2);
if (val < 0)
return 1;
if (val > 0)
return -1;
return 0;
}
void citire(FILE *input)
{
fscanf(input, "%ld", &N);
if(N < 3)
{
printf("Prea putine puncte.");
exit(-1);
}
for(int i = 0; i < N; i++)
{
fscanf(input, "%f %f", &puncte[i].x, &puncte[i].y);
if(puncte[i].x < puncte[stanga].x)
stanga = i;
else if(puncte[i].x == puncte[stanga].x)
if(puncte[i].y < puncte[stanga].y)
stanga = i;
}
Coord aux;
aux = puncte[0];
puncte[0] = puncte[stanga];
puncte[stanga] = aux;
qsort(puncte + 1, N - 1, sizeof(puncte[0]), compare);
}
void infasurare()
{
push(&stack, puncte[0]);
push(&stack, puncte[1]);
for(int i = 2; i < N; i++)
{
while(stack.vf >= 1 && cross(stack.st[stack.vf - 1], stack.st[stack.vf], puncte[i]) < 0)
pop(&stack);
push(&stack, puncte[i]);
}
}
void afisare(FILE *output)
{
fprintf(output, "%ld\n", stack.vf + 1);
for(int i = 0; i <= stack.vf; i++)
fprintf(output, "%f %f\n", stack.st[i].x, stack.st[i].y);
}
int main()
{
FILE *input, *output;
if((input = fopen("infasuratoare.in", "r")) == NULL)
{
perror("Eroare la deschidere fisier intrare.");
exit(-1);
}
citire(input);
stack.cap = MAX;
stack.vf = -1;
infasurare();
if((output = fopen("infasuratoare.out", "w")) == NULL)
{
perror("Eroare la deschidere fisier iesire.");
exit(-1);
}
afisare(output);
if(fclose(input) == -1)
{
perror("Eroare la inchidere fisier intrare.");
exit(-1);
}
if(fclose(output) == -1)
{
perror("Eroare la inchidere fisier iesire.");
exit(-1);
}
return 0;
}