團體程式設計天梯賽-練習集 L3-021 神壇
阿新 • • 發佈:2019-01-05
題目:點選開啟連結
題意:給出n個點,求出面積最小的三角形。(n<=5000)
分析:以一個點為中心,其他點圍繞這個點做一個極角排序,找出最小的三角形,三角形只能是這個點和相鄰兩個點組成的三角形,想象成太陽光發散的情形,這樣總的複雜度為O(n^2*logn),比完全暴力優化了不少,細節見程式碼。
程式碼:
#pragma comment(linker, "/STACK:102400000,102400000") #include<algorithm> #include<iostream> #include<iomanip> #include<cstdlib> #include<cstring> #include<string> #include<cstdio> #include<bitset> #include<vector> #include<cmath> #include<ctime> #include<stack> #include<queue> #include<deque> #include<list> #include<set> #include<map> using namespace std; #define debug test #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define ll long long #define ull unsigned long long #define pb push_back #define mp make_pair #define inf 0x3f3f3f3f #define eps 1e-10 #define MOD 1000000007 #define PI acos(-1.0) const int N = 5e3+10; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; int n; struct pt{ ll x,y; }p[N],tp[N]; bool cmp(pt a,pt b) { return b.y*a.x>a.y*b.x; } int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n; for(int i=1;i<=n;i++) cin>>p[i].x>>p[i].y; double ans=2e18; for(int i=1;i<=n;i++) { int t=1; for(int j=1;j<=n;j++) { if(i==j) continue; tp[t].x=p[j].x-p[i].x,tp[t].y=p[j].y-p[i].y,t++; } sort(tp+1,tp+t,cmp); for(int j=1;j<t-1;j++) ans=min(ans,(tp[j].x*tp[j+1].y-tp[j+1].x*tp[j].y)*0.5); } ///c++ 儲存指定小數位方法 cout<<setiosflags(ios::fixed)<<setprecision(3)<<ans<<endl; return 0; }