Hướng dẫn giải của Mảnh đất tổ tiên


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 happyboy99x

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<complex>
using namespace std;

typedef complex<double> Point;
const int N = 1000, TIME = 100;
Point mul (cos(M_PI/TIME), sin(M_PI/TIME));
Point p1[N], p2[N];
int m, n;

void enter(int &n, Point p[N]) {
    cin >> n;
    for(int i = 0; i < n; ++i)
        cin >> p[i].real() >> p[i].imag();
}

bool cmp(const Point &a, const Point &b) {
    return a.real() < b.real();
}

int main() {
    ios::sync_with_stdio(false);
    int tc; cin >> tc;
    while(tc--) {
        enter(m, p1); enter(n, p2);
        bool cut = true;
        for(int i = 0; i < TIME; ++i) {
            if(max_element(p1, p1+m, cmp)->real() < min_element(p2, p2+n, cmp)->real() ||
                    max_element(p2, p2+n, cmp)->real() < min_element(p1, p1+m, cmp)->real()) {
                cut = false;
                break;
            }
            for(int i = 0; i < m; ++i) p1[i] *= mul;
            for(int i = 0; i < n; ++i) p2[i] *= mul;
        }
        cout << (cut ? "YES" : "NO") << endl;
    }
    return 0;
}

Code mẫu của ladpro98

{$N+}
program NKLAND;
uses    math;
const   maxn = 1009;
        fi = '';
type    Point = record
                x,y: double;
        end;
        Line = record
                a,b,c: double;
        end;
var     a, b:array[0..maxn] of Point;
        t, tt, i, j, m, n: longint;
        la, lb, lc: double;
        Distinct: boolean;
        inp, oup:text;

procedure Extract(p1, p2: Point; var a, b, c: double);
begin
        a := p1.y - p2.y;
        b := p2.x - p1.x;
        with p1 do c := -(a*x + b*y);
end;

function SameSide(a, b: Point): boolean;
begin
        exit((a.x*la+a.y*lb+lc)*(b.x*la+b.y*lb+lc) >= 0);
end;

begin
        assign(inp,fi);reset(inp);
        readln(inp,t);
        for tt:=1 to t do begin
                readln(inp,m);
                for i:=1 to m do read(inp,a[i].x,a[i].y);
                readln(inp,n);
                for i:=1 to n do read(inp,b[i].x,b[i].y);
                a[0] := a[m]; a[m+1] := a[1];

                for i:=1 to m do begin
                        Extract(a[i], a[i+1], la, lb, lc);
                        Distinct := true;
                        for j:=1 to n do
                        if SameSide(a[i-1], b[j]) then begin
                                Distinct := false;
                                break;
                        end;
                        if Distinct then break;
                end;
                if Distinct then writeln('NO')
                else writeln('YES');
        end;
end.

Code mẫu của RR

//Written by RR
{$ifdef rr}
  {$r+,q+}
  {$mode objfpc}
  {$inline off}
{$else}
  {$r-,q-}
  {$mode objfpc}
  {$inline on}
{$endif}

uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXN          =       1111;
  alpha         =       pi/4;
type
  real          =       extended;
  point         =       record x,y:real; end;
var
  f1,f2         :       text;
  n1,n2,test    :       longint;
  a,b           :       array[1..MAXN] of point;
  sina,cosa,now :       real;
  ln,nn         :       real;
  intersect     :       boolean;

procedure openF;
    begin
      assign(f1,FINP); reset(f1);
      assign(f2,FOUT); rewrite(f2);
    end;
procedure closeF;
    begin
      close(f1);
      close(f2);
    end;

procedure quay(var a:point); inline;
    var
      u:point;
    begin
      u:=a;
      a.x:=u.x*cosa-u.y*sina;
      a.y:=u.y*cosa+u.x*sina;
    end;

begin
  openF;
  read(f1,test);
  sina:=sin(alpha); cosa:=cos(alpha);
  for test:=1 to test do
    begin
      read(f1,n1);
      for n1:=1 to n1 do
        with a[n1] do read(f1,x,y);
      read(f1,n2);
      for n2:=1 to n2 do
        with b[n2] do read(f1,x,y);
      now:=0;
      intersect:=true;
      while (now<=3.15) do
        begin
          now+=alpha;
          for n1:=1 to n1 do
            quay(a[n1]);
          for n2:=1 to n2 do
            quay(b[n2]);
          ln:=-2000111000; nn:=-ln;
          for n1:=1 to n1 do
            ln:=max(ln,a[n1].x);
          for n2:=1 to n2 do
            nn:=min(nn,b[n2].x);
          if ln<nn then
            begin
              writeln(f2,'NO');
              intersect:=false;
              break;
            end;
          ln:=-2000111000; nn:=-ln;
          for n1:=1 to n1 do
            nn:=min(nn,a[n1].x);
          for n2:=1 to n2 do
            ln:=max(ln,b[n2].x);
          if ln<nn then
            begin
              writeln(f2,'NO');
              intersect:=false;
              break;
            end;
        end;
      if intersect then writeln(f2,'YES');
    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;
}

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("NKLAND.in","r",stdin);

     scanf("%d",&test);
     for(int itest = 1;itest<=test;itest++){
          bool flag = false;   
          scanf("%d",&n);
          for(int i = 1;i<=n;i++) scanf("%d %d",&a[i].x,&a[i].y);
          scanf("%d",&m);
          for(int i = 1;i<=m;i++) scanf("%d %d",&b[i].x,&b[i].y); 
          n = graham(a,n);
          m = graham(b,m);
          for(int i = 1;i<=n;i++){
                if(namtrong(a[i],1,m,b)){
                     flag = true;
                     break;
                }
          }
          if(!flag) for(int i = 1;i<=m;i++){
                if(namtrong(b[i],1,n,a)){
                     flag = true;
                     break;
                }
          }
          if(flag) printf("YES\n");
          else printf("NO\n");        
     }
    // getch();
}

Code mẫu của skyvn97

#include<cstdio>
#include<cmath>
#define MAX   1111
const double PI=acos(-1.0);
const double INF=2e9;
struct point {
    double x,y;
    point(){}
    point(const double &_x,const double &_y) {
        x=_x;y=_y;
    }
    point rotate(const double &alpha) {
        return (point(x*cos(alpha)-y*sin(alpha),x*sin(alpha)+y*cos(alpha)));
    }
};
double min(const double &x,const double &y) {
    if (x<y) return (x); else return (y);
}
double max(const double &x,const double &y) {
    if (x>y) return (x); else return (y);
}
int m,n;
point a[MAX];
point b[MAX];
void init(void) {
    int i;
    scanf("%d",&m);
    for (i=1;i<=m;i=i+1) {
        scanf("%lf",&a[i].x);
        scanf("%lf",&a[i].y);
    }
    scanf("%d",&n);
    for (i=1;i<=n;i=i+1) {
        scanf("%lf",&b[i].x);
        scanf("%lf",&b[i].y);
    }
}
void check(void) {
    int i,j;
    double alpha;
    double mxa,mna,mxb,mnb;
    for (i=0;i<100;i=i+1) {
        alpha=i*PI/100.0;
        mxa=-INF;mna=INF;
        mxb=-INF;mnb=INF;
        for (j=1;j<=m;j=j+1) {
            mxa=max(mxa,a[j].rotate(alpha).x);
            mna=min(mna,a[j].rotate(alpha).x);
        }
        for (j=1;j<=n;j=j+1) {
            mxb=max(mxb,b[j].rotate(alpha).x);
            mnb=min(mnb,b[j].rotate(alpha).x);
        }
        if (mxa<mnb) {
            printf("NO\n");
            return;
        }
        if (mxb<mna) {
            printf("NO\n");
            return;
        }
    }
    printf("YES\n");
}
int main(void) {
    int t,c;
    scanf("%d",&t);
    for (c=1;c<=t;c=c+1) {
        init();
        check();
    }
    return 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.