Hướng dẫn giải của Maximum Triangle Area
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của ladpro98
#include <iostream> #include <iomanip> #include <cstdio> #include <algorithm> #define ii pair<int, int> #define X first #define Y second const int N = 50005; using namespace std; ii a[N], H[N]; int n, k; void operator -= (ii &A, ii B) {A.X -= B.X; A.Y -= B.Y;} bool ccw(ii A, ii B, ii C) {C -= B; B -= A; return B.X * C.Y >= B.Y * C.X;} int area(int i, int j, int k) {return abs(H[i].X * (H[j].Y - H[k].Y) + H[j].X * (H[k].Y - H[i].Y) + H[k].X * (H[i].Y - H[j].Y));} int Find(int l, int r) { int ll = l, rr = r, S = 0; while (ll < rr) { int m = ll + rr >> 1; int p = area(l, m, r), q = area(l, m + 1, r); if (p <= q) ll = m + 1; else rr = m; S = max(S, max(p, q)); } return S; } int Search(int l, int r) { int ll = l + 1, rr = r - 1, S = 0; while (ll < rr) { int m = ll + rr >> 1; int p = Find(l, m), q = Find(l, m + 1); if (p <= q) ll = m + 1; else rr = m; S = max(S, max(p, q)); } return S; } int main() { ios :: sync_with_stdio(0); cin.tie(0); while (cin >> n) { if (n == -1) break; for(int i = 0; i < n; i++) cin >> a[i].X >> a[i].Y; sort(a, a + n); int k = 0; for(int i = 0; i < n; i++) { while (k >= 2 && ccw(H[k - 2], H[k - 1], a[i])) k--; H[k++] = a[i]; } for(int i = n - 2, t = k + 1; i >= 0; i--) { while (k >= t && ccw(H[k - 2], H[k - 1], a[i])) k--; H[k++] = a[i]; } k--; int res = 0; for(int i = 0; i < k; i++) res = max(res, Search(i, k)); cout << setprecision(2) << fixed << (double)res / 2 << '\n'; } return 0; }
Code mẫu của RR
//Written by Nguyen Thanh Trung {$R+,Q+} {$Mode objFPC} uses math; const FINP = ''; FOUT = ''; MAXN = 50111; eps = 1e-6; type point = record x,y:longint; end; var f1,f2 : text; n : longint; a,ch : array[0..MAXN] of point; procedure openF; begin assign(f1,FINP); reset(f1); assign(f2,FOUT); rewrite(f2); end; procedure closeF; begin close(f1); close(f2); end; procedure swap(var a,b:point); inline; var temp:point; begin temp:=a; a:=b; b:=temp; end; function CCW(p1,p2,p3:point):longint; var a1,a2,b1,b2,c1,c2,t:double; begin a1:=p2.x-p1.x; b1:=p2.y-p1.y; a2:=p3.x-p2.x; b2:=p3.y-p2.y; t:=a1*b2-a2*b1; if abs(t)<eps then exit(0) else if t<0 then exit(-1) else exit(1); end; function lower2(p1,p2:point):boolean; var a1,a2,b1,b2,t:double; begin a1:=p1.x-a[0].x; b1:=p1.y-a[0].y; a2:=p2.x-a[0].x; b2:=p2.y-a[0].y; t:=a1*b2-a2*b1; lower2:=false; if t>eps then lower2:=true else if (abs(t)<eps) then exit(p1.x<p2.x); end; function lower(p1,p2:point):boolean; var a1,a2,b1,b2,t:double; begin a1:=p1.x-a[1].x; b1:=p1.y-a[1].y; a2:=p2.x-a[1].x; b2:=p2.y-a[1].y; t:=a1*b2-a2*b1; lower:=false; if t>eps then lower:=true else if (abs(t)<eps) then lower:=lower2(p1,p2); end; procedure sort(l,r:longint); var i,j:longint; mid:point; begin i:=l; j:=r; mid:=a[l+random(r-l+1)]; repeat while lower(a[i],mid) do inc(i); while lower(mid,a[j]) do dec(j); if i<=j then begin swap(a[i],a[j]); inc(i); dec(j); end; until i>j; if i<r then sort(i,r); if l<j then sort(l,j); end; procedure graham; var i,c:longint; begin c:=1; for i:=2 to n do if (a[i].y<a[c].y) or ((a[i].y=a[c].y) and (a[i].x<a[c].x)) then c:=i; swap(a[c],a[1]); a[0]:=a[1]; a[0].x-=1; if n>2 then sort(2,n); i:=n; n:=2; ch[1]:=a[1]; ch[2]:=a[2]; for i:=3 to i do begin while (n>1) and (CCW(ch[n-1],ch[n],a[i])<>1) do dec(n); inc(n); ch[n]:=a[i]; end; end; function dt(i,j,k:point):longint; begin exit(abs((j.x-i.x)*(j.y+i.y) +(k.x-j.x)*(k.y+j.y) +(i.x-k.x)*(i.y+k.y))); end; procedure inp; var i:longint; begin for i:=1 to n do with a[i] do read(f1,x,y); end; procedure solve; var i,j,ii,temp,best,now:longint; begin if n<3 then begin writeln(f2,'0.00'); exit; end; best:=dt(ch[1],ch[2],ch[3]); for i:=1 to n-2 do begin ii:=i+1; for j:=i+2 to n do begin now:=0; repeat temp:=dt(ch[ii],ch[i],ch[j]); if temp>=now then now:=temp else break; inc(ii); if ii>j then break; until false; dec(ii); best:=max(best,now); end; //for j end; //for i for i:=1 to n-2 do begin ii:=i+3; for j:=i+2 to n-1 do begin now:=0; repeat temp:=dt(ch[ii],ch[i],ch[j]); if temp>=now then now:=temp else break; inc(ii); if ii>n then break; until false; dec(ii); best:=max(best,now); end; end; //for i writeln(f2,best/2:0:2); end; procedure duyet; var i,j,k,li,lj,lk,best:longint; begin best:=0; for i:=1 to n do for j:=1 to n do for k:=1 to n do if dt(a[i],a[j],a[k])>best then begin best:=dt(a[i],a[j],a[k]); li:=i; lj:=j; lk:=k; end; writeln(f2,best/2:0:2,' ',li,' ',lj,' ',lk); end; var test:longint; begin openF; read(f1,n); test:=0; while (n>0) do begin inc(test); inp; graham; solve; read(f1,n); end; closeF; end.
Code mẫu của hieult
#include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<cassert> #include<ctime> #include<algorithm> #include<iterator> #include<iostream> #include<cctype> #include<string> #include<vector> #include<map> #include<set> #include<queue> #include<list> //#include<conio.h> #define oo 1111111111 #define nmax 100111 #define MAX 222 using namespace std; struct point{ int x,y; bool operator == (point D) const{ return (x == D.x && y == D.y); } }; point a[nmax],b[nmax],p; int n,m,N,test; long long kc(point a,point b){ long long X = (b.x-a.x); long long Y = (b.y-a.y); return X*X+Y*Y; } double dientich(point a,point b,point c){ double KQ = 0.5*((a.x*1.*b.y-a.y*1.*b.x)+(b.x*1.*c.y-b.y*1.*c.x)+(c.x*1.*a.y-c.y*1.*a.x)); return KQ>0?KQ:-KQ; } bool behon(point a,point b,point bn){ long long ax,ay,bx,by; ax = a.x - bn.x; ay = a.y - bn.y; bx = b.x - bn.x; by = b.y - bn.y; if(ay!=0 && by==0) return true; if(ay==0||by==0) return false; return ax*by>ay*bx; } void Sort(point a[],int l,int r){ int i = l,j = r; point mid = a[(l+r)/2]; while(i<j){ while(behon(a[i],mid,a[0])) i++; while(behon(mid,a[j],a[0])) j--; if(i<=j) swap(a[i++],a[j--]); } if(i<r) Sort(a,i,r); if(l<j) Sort(a,l,j); } int ccw(point p1,point p2,point p3){ long long a1,a2,b1,b2,t; a1 = p2.x-p1.x; a2 = p3.x-p1.x; b1 = p2.y-p1.y; b2 = p3.y-p1.y; t = a1*b2-a2*b1; if(t==0) return 0; if(t>0) return 1; return -1; } int graham(point a[],int n){ int m = 1; for(int i = 2;i<=n;i++) if(a[m].y>a[i].y) m = i; for(int i = 1;i<=n;i++) if(a[i].y==a[m].y && a[i].x>a[m].x) m = i; swap(a[1],a[m]); a[0].x = a[1].x; a[0].y = a[1].y-1; Sort(a,2,n); a[++n] = a[1]; m = 2; bool ok = true; for(int i = 3;i<=n;i++){ ok = true; while(ccw(a[m],a[m-1],a[i])>=0){ if(ccw(a[m],a[m-1],a[1])==0){ ok = false; if(kc(a[m],a[m-1])<kc(a[m-1],a[i])) swap(a[m],a[i]); break; } else m--; } if(ok) swap(a[++m],a[i]); } return --m; } long long stg(point a,point b,point c){ long long s = (b.x-a.x)*1LL*(b.y+a.y)+(c.x-b.x)*1LL*(c.y+b.y)+ (a.x-c.x)*1LL*(a.y+c.y); return s>0?s:-s; } int thuoc(point a,point b,point c){ if(ccw(a,b,c)==0 && ((a.y<=c.y && c.y<=b.y)||(a.y>=c.y && c.y>=b.y))) return true; else return false; } int namtrong(point p,int l,int r,point b[]){ while(r-l>2){ int mid = (l+r+1)/2; int k = ccw(b[1],b[mid],p); if(k==0){ if((b[1].x-p.x)*(b[mid].x-p.x)<0) return 1;; return 0; } if(k==1) l = mid-1; if(k==-1) r = mid; } point x,y,z; x = b[1]; y = b[r]; z = b[r-1]; long long k = stg(x,y,z); long long t = stg(x,y,p)+stg(x,z,p)+stg(y,z,p); if(t>k) return 0; int kk = ccw(x,y,p)*ccw(x,z,p)*ccw(y,z,p); if(kk!=0) return 1; if(p==x||p==y||p==z) return 0; if(r==3){ if(n<=3) return 0; if(ccw(x,y,p)==0) return 1; } if(r==n &&ccw(x,z,p)==0) return 1; if(ccw(x,y,p)==0 && r!=n) return 1; if(ccw(x,z,p)==0 && r!=3) return 1; return 0; } int main(){ // freopen("input.in","r",stdin); // freopen("output.out","w",stdout); while(scanf("%d",&n)>0 && n>0){ for(int i = 1;i<=n;i++) scanf("%d %d",&a[i].x,&a[i].y); n = graham(a,n); for(int i = n + 1; i <= 2 * n; i++){ a[i] = a[i - n]; } double kq = 0; // printf("%d\n",n); for(int i = 1;i<=n;i++){ int u = i + 1; for(int j = i + 1;j<=n;j++){ while(dientich(a[i],a[j],a[u + 1]) > dientich(a[i], a[j], a[u]) && u < n) u++; // printf("%d %d %d\n",i,j,u); kq = max(kq, dientich(a[i], a[j], a[u])); } } printf("%.2lf\n",kq); } //getch(); }
Code mẫu của ll931110
#include <algorithm> #include <bitset> #include <cmath> #include <ctime> #include <cstdio> #include <cstdlib> #include <cstring> #include <deque> #include <fstream> #include <functional> #include <iostream> #include <map> #include <set> #include <sstream> #include <stack> #include <queue> #include <utility> #include <vector> using namespace std; vector< pair<int,int> > point; int n; int cross_product(pair<int,int> A,pair<int,int> B,pair<int,int> C) { int xa = B.first - A.first,ya = B.second - A.second; int xb = C.first - B.first,yb = C.second - B.second; return xa * yb - xb * ya; } int area(pair<int,int> A,pair<int,int> B,pair<int,int> C) { return abs(cross_product(A,B,C)); } vector< pair<int,int> > convex_hull(vector< pair<int,int> > v) { if (n < 3) return v; sort(v.begin(),v.end()); pair<int,int> p1 = v[0],p2 = v[n - 1]; vector< pair<int,int> > up,down; up.push_back(p1); down.push_back(p1); for (int i = 1; i < n; i++) { int cross = cross_product(p1,v[i],p2); if (i == n - 1 || cross > 0) { while (down.size() > 1 && cross_product(down[down.size() - 2],down[down.size() - 1],v[i]) <= 0) down.pop_back(); down.push_back(v[i]); } if (i == n - 1 || cross < 0) { while (up.size() > 1 && cross_product(up[up.size() - 2],up[up.size() - 1],v[i]) >= 0) up.pop_back(); up.push_back(v[i]); } } for (int i = up.size() - 2; i > 0; i--) down.push_back(up[i]); return down; } int optimal(vector< pair<int,int> > v) { n = v.size(); if (n < 3) return 0; int a = 0,b = 1,c = 2,ret = area(v[0],v[1],v[2]); while (1) { while (1) { int _c = c + 1; if (_c >= n) _c = 0; if (area(v[a],v[b],v[_c]) > area(v[a],v[b],v[c])) { ret = max(ret,area(v[a],v[b],v[_c])); c = _c; } else break; } while (1) { int _b = b + 1; if (_b >= n) _b = 0; if (area(v[a],v[_b],v[c]) > area(v[a],v[b],v[c])) { ret = max(ret,area(v[a],v[_b],v[c])); b = _b; } else break; } bool flag = false; while (1) { int _a = a + 1; if (_a >= n) _a = 0; if (area(v[_a],v[b],v[c]) > area(v[a],v[b],v[c])) { flag = true; ret = max(ret,area(v[_a],v[b],v[c])); a = _a; } else break; } if (!flag) { a++; if (a >= n) a = 0; if (a == b) { b++; if (b >= n) b = 0; } if (b == c) { c++; if (c >= n) c = 0; } } if (a == 0) break; } return ret; } int main() { // freopen("mtriarea.in","r",stdin); // freopen("mtriarea.ou","w",stdout); while (1) { scanf("%d", &n); if (n < 0) return 0; point.resize(n); for (int i = 0; i < n; i++) scanf("%d %d", &point[i].first, &point[i].second); point = convex_hull(point); printf("%.2lf\n", optimal(point)/2.0); } }
Bình luận