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.
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