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.

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

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.