Cod sursa(job #686187)

Utilizator iuliannnTatar Cornel iuliannn Data 21 februarie 2012 14:57:05
Problema Infasuratoare convexa Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.19 kb
#include <iostream>
#include <cmath>
#define PI 3.141592
using namespace std;

int n = 13;
int coord[100][2] = {0, 0, 1, 7, 2, 11, 5, 12, 7, 13, 10, 8, 14, 12, 16, 10, 17, 6, 13, 2, 11, 1, 8, 1, 5, 1, 2, 3, 1, 7};
int st[100];
double unghi[100];
double sinus[100];

void Swap(int, int);
void quick(int, int);
int poz(int, int);
double calculeaza_sinus(int, int, int);
double dist(int, int);
double calc_unghi(int a,int b,int c)
{
      double x1,x2,x3,y1,y2,y3;
      x1=coord[a][0];
      y1=coord[a][1];
      x2=coord[b][0];
      y2=coord[b][1];
      x3=coord[c][0];
      y3=coord[c][1];
      double det = 0;
      det += (x1 * y2 + x2 * y3 + x3 * y1);
      det -= (y2 * x3 + y3 * x1 + y1 * x2);
      return det;
}

void afisez(int c)
{
    int i;
    for (i = 1; i < c; i++) cout << st[i] << ' ';
}

void back(int p)
{int pval;
    for(pval=st[p-1]+1;pval<=n+1;pval++)
    {st[p]=pval;
      
      if (calc_unghi(st[p-2],st[p-1],st[p])==0) {st[p-1]=pval;p=p-1;back(p+1);}
      if (calc_unghi(st[p-2],st[p-1],st[p])>0);
        if (st[p]==14)
          afisez(p);
          else 
          back(p+1);
      }
}
        
int main()
{
  int i;
//  cin >> n;
  for (i = 1; i <= n; i++)
  {
//      cin >> coord[i][0] >> coord[i][1];
      if (coord[i][1] < coord[1][1]) Swap(i, 1);
      else if (coord[i][1] == coord[1][1])
      {
        if (coord[i][0] < coord[1][0]) Swap(i, 1);
      }
  }
  for (i = 2; i <= n; i++)
  {
      unghi[i] = atan(double(coord[i][1] - coord[1][1]) / double(coord[i][0] - coord[1][0]));
      unghi[i] *= 180 / PI;
      if (unghi[i] < 0) unghi[i] += 180;
  }
  quick(2, n);
  st[1] = 1;st[2]=2;
  back(3);
  /*
  for (i = 1; i <= n; i++)
  {
      cout << coord[i][0] << ' ' << coord[i][1] << '\t' << unghi[i] << '\t' << calc_unghi(i -1, i, i + 1) << endl;
  }
  */
  /*
  st[1]=1;st[2]=2;
  int p=2,punct=3;
  do
  {st[++p]=punct;
    while (calc_unghi(st[p-2],st[p-1],punct) <= 0) p=p-1;

    }
    while(st[p]!=st[1]);
  for (i = 1; i <= p; i++)
        cout << coord[i][0] << ' ' << coord[i][1] << endl;
    */
  system ("pause");
  return 0;
}

double dist(int a, int b)
{
  double distanta = 0;
  distanta += (coord[a][0] - coord[b][0]) * (coord[a][0] - coord[b][0]);
  distanta += (coord[a][1] - coord[b][1]) * (coord[a][1] - coord[b][1]);
  return sqrt(distanta);
}

double calculeaza_sinus(int A, int B, int C)
{
  double a, b, c, p;
  a = dist (B, C);
  b = dist (A, C);
  c = dist (A, B);
  p = (a + b + c) / 2;
  return 2 * sqrt(p * (p - a) * (p - b) * (p - c)) / (a * c);
}

void Swap(int i, int j)
{
  int aux;
  aux = coord[i][0];
  coord[i][0] = coord[j][0];
  coord[j][0] = aux;
  aux = coord[i][1];
  coord[i][1] = coord[j][1];
  coord[j][1] = aux;
  double aux2;
  aux2 = unghi[i];
  unghi[i] = unghi[j];
  unghi[j] = aux2;
}

int poz(int i, int j)
{
  int m = 0;
  while (i < j)
  {
      if (unghi[i] > unghi[j])
      {
        Swap(i, j);
        m = 1 - m;
      }
      i += m;
      j -= 1 - m;
  }
  return i;
}

void quick(int li, int ls)
{
  if (li < ls)
  {
      int k = poz(li, ls);
      quick(li, k - 1);
      quick(k + 1, ls);
  }
}