程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 圈地(斜率排序+坐標系旋轉)

圈地(斜率排序+坐標系旋轉)

編輯:C++入門知識

Problem 2 圈地(land.cpp/c/pas) 【題目描述】 2維平面上有n個木樁,你有一次圈地的機會並得到圈到的土地,為了體現你的高風亮節,你要使你圈到的土地面積盡量小。圈地需要圈一個至少3個點的多邊形,多邊形的頂點就是一個木樁,圈得的土地就是這個多邊形內部的土地。   【輸入格式】 第一行一個整數n,表示木樁個數。   接下來n行,每行2個整數表示一個木樁的坐標,坐標兩兩不同。 【輸出格式】 僅一行,表示最小圈得的土地面積,保留2位小數。 【樣例輸入】 樣例1: 3 0 0 0 1 1 0 樣例2: 4 0 0 0 1 0 2 1 1 【樣例輸出】 樣例1: 0.50 樣例2: 0.00 【數據范圍】     對於10%的數據,n<=100;  對於30%的數據,n<=300;  對於50%的數據,n<=500;  對於100%的數據,n<=1000。   顯然這題的多邊形一定是三角形。 首先求出所有邊,按k排序(必須先求出來,不能直接在排序的時候求) 然後考慮這些邊,會發現正好是繞坐標系旋轉一圈。 也就是說如果按照以這邊為y軸從左至右排序,那麼每轉移一條邊,只需要調換該邊2個點的位置 這題沒給范圍,但是必須用long long [cpp]  #include<cstdio>   #include<cstdlib>   #include<cstring>   #include<algorithm>   #include<functional>   #include<iostream>   #include<cmath>   using namespace std;   #define MAXN (1000+10)   #define INF (1000000000)   #define eps 1e-10   struct P   {       int x,y;       long long operator*(const P &b)       {           return (long long)x*b.y-(long long)b.x*y;       }       friend bool operator<(P a,P b){if (a.x^b.x)  return a.x<b.x;return a.y<b.y;}   }a[MAXN];   long long abs2(long long x){if (x>0) return x;return -x;}   int n,h[MAXN];   struct E   {       int i,j;       double k;       E(){}       E(int _i,int _j):i(_i),j(_j){if (a[i].x==a[j].x) k=1e10;else k=(double)(a[i].y-a[j].y)/(a[i].x-a[j].x);}       friend bool operator<(E a,E b){return a.k<b.k;    }   }e[MAXN*MAXN/2];   long long S2(P A,P B,P C)   {       return abs2(A*B+B*C+C*A);   }   int size=0;   int main()   {       freopen("land.in","r",stdin);       freopen("land.out","w",stdout);       scanf("%d",&n);       for (int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);       long long ans=(long long)1<<60;       /*        for (int i=1;i<=n-2;i++)          for (int j=i+1;j<n;j++)              for (int k=j+1;k<=n;k++)                  ans=min(ans,abs2(a[i]*a[j]+a[j]*a[k]+a[k]*a[i]));      */              sort(a+1,a+1+n);       for (int i=1;i<=n;i++) h[i]=i;       for (int i=1;i<n;i++)           for (int j=i+1;j<=n;j++)           {               e[++size]=E(i,j);                      }              sort(e+1,e+1+size);              for (int i=1;i<=size&&ans;i++)       {           if (h[e[i].i]>1&&h[e[i].i]<n) ans=min(ans,S2(a[h[e[i].i]-1],a[h[e[i].i]],a[h[e[i].i]+1]));           if (h[e[i].j]>1&&h[e[i].j]<n) ans=min(ans,S2(a[h[e[i].j]-1],a[h[e[i].j]],a[h[e[i].j]+1]));           swap(a[h[e[i].i]],a[h[e[i].j]]);           swap(h[e[i].i],h[e[i].j]);       }              printf("%.2lf",(double)ans/2);       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved