Hướng dẫn giải của Sao đa giác


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 <cstdio>
#include <algorithm>
#include <cmath>

#define X first
#define Y second

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, a, b) for(int i = (a); i <=(b); i++)

const int N = 55;
const double EPS = 1e-8;

using namespace std;

//BEGIN OF HELPERS

typedef pair<double, double> point;

bool eq(double a, double b) {return fabs(a - b) < EPS;}

struct line {
    point P, Q;
    double a, b, c; //aX + bY = c
    line(point p, point q) {
        P = p; Q = q;
        a = Q.Y - P.Y;
        b = P.X - Q.X;
        c = a * P.X + b * P.Y;
    }
};

point cutPoint(line d1, line d2) {
    double  D = d1.a * d2.b - d1.b * d2.a;
    double Dx = d1.c * d2.b - d1.b * d2.c;
    double Dy = d1.a * d2.c - d1.c * d2.a;
    return point(Dx / D, Dy / D);
}

double area(point a, point b, point c)
    {return fabs(a.X * (b.Y - c.Y) + b.X * (c.Y - a.Y) + c.X * (a.Y - b.Y));}

//END OF HELPERS

int n;
point a[N];
double polyArea;

bool isGood(point C) {
    double sumArea = 0;
    REP(i, 1, n)
        sumArea += area(a[i], a[i + 1], C);
    return eq(sumArea, polyArea);
}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    while (cin >> n) {
        if (n == 0) break;
        REP(i, 1, n) cin >> a[i].X >> a[i].Y;
        a[n + 1] = a[1];

        polyArea = 0;
        REP(i, 1, n) polyArea += (a[i].X - a[i + 1].X) * (a[i].Y + a[i + 1].Y);
        polyArea = fabs(polyArea);

        bool isStarShape = 0;
        FOR(i, 1, n) REP(j, i + 1, n)
        if (isGood(cutPoint(line(a[i], a[i + 1]), line(a[j], a[j + 1])))) {
            isStarShape = 1; break;
        }
        cout << isStarShape << '\n';
    }
    return 0;
}

Code mẫu của RR

{$R+,Q+,N+}
const
  FINP='';
  FOUT='';
  MAXN=51;
  eps=1e-6;
var
  x,y:array[1..MAXN] of double;
  s:double;
  f1,f2:text;
  n:longint;
procedure openF;
begin
  assign(f1,FINP); reset(f1);
  assign(f2,FOUT); rewrite(f2);
end;
procedure closeF;
begin
  close(f1); close(f2);
end;
procedure inp;
var
  i:longint;
begin
  for i:=1 to n do
    read(f1,x[i],y[i]);
  x[n+1]:=x[1]; y[n+1]:=y[1];
  s:=0;
  for i:=1 to n do
    s:=s+x[i]*y[i+1]-y[i]*x[i+1];
  s:=abs(s);
end;
function inPoly(xx,yy:double):boolean;
var
  i:longint;
  ss:double;
begin
  ss:=0;
  for i:=1 to n do
    ss:=ss+abs(xx*y[i]-yy*x[i]+x[i]*y[i+1]-y[i]*x[i+1]+x[i+1]*yy-y[i+1]*xx);
  inPoly:=abs(ss-s)<=eps;
end;
function CCW(x1,y1,x2,y2,x3,y3:double):integer;
var
  t,a1,a2,b1,b2:double;
begin
  a1:=x2-x1;
  b1:=y2-y1;
  a2:=x3-x2;
  b2:=y3-y2;
  t:=a1*b2-a2*b1;
  if abs(t)<eps then CCW:=0
  else if t<0 then CCW:=-1
  else CCW:=1;
end;
function intersect(x1,y1,x2,y2,x3,y3,x4,y4:double):boolean;
begin
  intersect:=(CCW(x1,y1,x2,y2,x3,y3)*CCW(x1,y1,x2,y2,x4,y4)=-1)
         and (CCW(x3,y3,x4,y4,x1,y1)*CCW(x3,y3,x4,y4,x2,y2)=-1);
end;
function seeAll(xx,yy:double;i,j:longint):boolean;
var
  ii,jj:longint;
begin
  if not inPoly(xx,yy) then exit(false);
  for ii:=1 to n do
    for jj:=1 to n do
    if (jj<>i) and (jj<>j) and (jj<>ii) then
      if intersect(xx,yy,x[ii],y[ii],x[jj],y[jj],x[jj+1],y[jj+1])
      then exit(false);
  exit(true);
end;
procedure solve;
var
  xx,yy,a1,a2,b1,b2,c1,c2,dd,dx,dy:double;
  i,j:longint;
begin
  for i:=1 to n-1 do
  for j:=i+1 to n do
    begin
      a1:=y[i+1]-y[i];
      a2:=y[j+1]-y[j];
      b1:=x[i]-x[i+1];
      b2:=x[j]-x[j+1];
      c1:=x[i+1]*y[i]-y[i+1]*x[i];
      c2:=x[j+1]*y[j]-y[j+1]*x[j];
      dd:=a1*b2-a2*b1;
      if abs(dd)<=eps then continue;
      dx:=b1*c2-b2*c1;
      dy:=c1*a2-c2*a1;
      xx:=dx/dd; yy:=dy/dd;
      if seeAll(xx,yy,i,j) then
        begin
          writeln(f2,1);
          exit;
        end;
    end;
  writeln(f2,0);
end;
begin
  openF;
  read(f1,n);
  while (n>0) do
    begin
      inp;
      solve;
      read(f1,n);
    end;
  closeF;
end.

Code mẫu của hieult

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef long double ld;
//typedef double ld;
typedef unsigned int ui;
typedef unsigned long long ull;

#define Rep(i,n) for(__typeof(n) i = 0; i < (n); ++i)
#define Repd(i,n) for(__typeof(n) i = (n)-1; i >= 0; --i)
#define For(i,a,b) for(__typeof(b) i = (a); i <= (b); ++i)
#define Ford(i,a,b) for(__typeof(a) i = (a); i >= (b); --i)
#define Fit(i,v) for(__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++i)
#define Fitd(i,v) for(__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++i)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sz(a) ((int)(a).size())
#define all(a) (a).begin(), (a).end()
#define ms(a,x) memset(a, x, sizeof(a))
#define nl puts("")
#define sp printf(" ")
#define ok puts("ok")
//#include <conio.h>

template<class F, class T> T convert(F a, int p = -1) { stringstream ss; if (p >= 0) ss << fixed << setprecision(p); ss << a; T r; ss >> r; return r; }
template<class T> void db(T a, int p = -1) { if (p >= 0) cout << fixed << setprecision(p); cout << a << " "; }
template<class T> T gcd(T a, T b) { T r; while (b != 0) { r = a % b; a = b; b = r; } return a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T> T sqr(T x) { return x * x; }
template<class T> T cube(T x) { return x * x * x; }
template<class T> struct Triple { T x, y, z; Triple() {} Triple(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {} };
template<class T> Triple<T> euclid(T a, T b) { if (b == 0) return Triple<T>(1, 0, a); Triple<T> r = euclid(b, a % b); return Triple<T>(r.y, r.x - a / b * r.y, r.z); }
template<class T> int getbit(T s, int i) { return (s >> i) & 1; }
template<class T> T onbit(T s, int i) { return s | (T(1) << i); }
template<class T> T offbit(T s, int i) { return s & (~(T(1) << i)); }
template<class T> int cntbit(T s) { return s == 0 ? 0 : cntbit(s >> 1) + (s & 1); }
const int bfsz = 1 << 16; char bf[bfsz + 5]; int rsz = 0;int ptr = 0;
char gc() { if (rsz <= 0) { ptr = 0; rsz = fread(bf, 1, bfsz, stdin); if (rsz <= 0) return EOF; } --rsz; return bf[ptr++]; }
void ga(char &c) { c = EOF; while (!isalpha(c)) c = gc(); }
int gs(char s[]) { int l = 0; char c = gc(); while (isspace(c)) c = gc(); while (c != EOF && !isspace(c)) { s[l++] = c; c = gc(); } s[l] = '\0'; return l; }
template<class T> bool gi(T &v) {
    v = 0; char c = gc(); while (c != EOF && c != '-' && !isdigit(c)) c = gc(); if (c == EOF) return false; bool neg = c == '-'; if (neg) c = gc();
    while (isdigit(c)) { v = v * 10 + c - '0'; c = gc(); } if (neg) v = -v; return true;
}

const double PI = 2 * acos(0);
const string months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int dr[] = {0, 0, -1, +1};
const int dc[] = {-1, +1, 0, 0};
const int inf = (int)1e9 + 5;
const ll linf = (ll)1e16 + 5;
const ld eps = ld(1e-9);
const ll mod = 100000007;
typedef pair<int, int> II;


#define maxn 55
#define maxv 1005

struct Point{
    ld x, y;
    Point() {};
    Point(ld _x, ld _y){
        x = _x; y = _y;
    }
};

Point O;

bool dcmp(ld x, ld y){
    return abs(x - y) < eps;
}

bool dcmpPoint(Point A, Point B){
    return dcmp(A.x, B.x) && dcmp(A.y, B.y);
}

int ccw(Point A, Point B, Point C){
    ld dx1 = B.x - A.x, dy1 = B.y - A.y;
    ld dx2 = C.x - A.x, dy2 = C.y - A.y;
    ld ret = dx1 * dy2 - dy1 * dx2;
    if(dcmp(ret, 0)) return 0;
    return ret < 0 ? -1 : 1;
}

ld sqrDist(Point P1, Point P2){
    return sqr(P1.x - P2.x) + sqr(P1.y - P2.y);
}

bool nearer(Point P1, Point P2){
    return sqrDist(O, P1) < sqrDist(O, P2);
}

bool cmp(Point P1, Point P2){
    int c = ccw(O, P1, P2);
    if(c != 0) return c > 0;
    return nearer(P1, P2);
}

void graham(Point a[], int &n){
    if(n < 3) return;
    int imin = 0;
    For(i, 1, n - 1) if((a[i].y < a[imin].y) || (a[i].y == a[imin].y && a[i].x < a[imin].x)) imin = i;
    O = a[imin];
    swap(a[0], a[imin]);
    sort(a + 1, a + n, cmp);
    int inow = 1;
    For(i, 2, n - 1){
        while(inow > 0 && ccw(a[i], a[inow], a[inow - 1]) >= 0) --inow;
        ++inow;
        swap(a[inow], a[i]);
    }
    n = inow + 1;
}

void getLine(Point P0, Point P1, ld &a, ld &b, ld &c){
    a = P1.y - P0.y; b = P0.x - P1.x; c = -(a * P0.x + b * P0.y);
}

bool getIntersect(Point P0, Point P1, Point P2, Point P3, Point &P4){
    ld a0, b0, c0, a1, b1, c1;
    getLine(P0, P1, a0, b0, c0);
    getLine(P2, P3, a1, b1, c1);
    ld d = a0 * b1 - a1 * b0;
    ld dx = b0 * c1 - b1 * c0;
    ld dy = c0 * a1 - c1 * a0;

    if(dcmp(d, 0)) return 0;

    P4 = Point(dx / d, dy / d);
    return 1;
}

ld area(Point a[], int n){
    ld res = 0;
    Rep(i, n) res += (a[i].x * a[(i + 1) % n].y - a[i].y * a[(i + 1) % n].x);
    return abs(res) / 2;
}

int n, m;
Point A[maxn];

bool thoaman(Point P){
    int id = 0, t;
    Rep(i, n){
        t = ccw(A[i], A[(i + 1) % n], P);
        if(t != 0){
            if(id * t < 0) return false;
            id = t;
        }
    }
    return true;
}

int main(){
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);

    while((cin >> n) && n > 0){
        Point P;
        Rep(i, n) cin >> A[i].x >> A[i].y;
        int check = 0;
        Rep(i, n) For(j, i + 1, n - 1){
            if(getIntersect(A[i], A[(i + 1) % n], A[j], A[(j + 1) % n], P)){
                if(thoaman(P)){
                    check = 1;
                    break;
                }
            }
        }
        cout << check << endl;
    }

    return 0;
}

Code mẫu của ll931110

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#define inf 1e13
#define eps 1e-8
using namespace std;

struct point
{
    double x,y;
    point (double _x,double _y)
    {
        x = _x;  y = _y;
    }
};

double area(vector<point> v)
{
    v.push_back(v[0]);
    double ans = 0;
    for (int i = 0; i + 1 < v.size(); i++) ans += (v[i].x * v[i + 1].y - v[i + 1].x * v[i].y);
    return ans;
}

vector<point> redirect(vector<point> v)
{
    double tmp = area(v);
    if (tmp < 0) reverse(v.begin(),v.end());
    return v;
}

void line(point p1,point p2, double &a, double &b, double &c)
{
    b = p1.x - p2.x; a = p2.y - p1.y;  c = -(a * p1.x + b * p1.y);
}

point intersect(point p1,point p2,point q1,point q2)
{
    double a1,b1,c1,a2,b2,c2;
    line(p1,p2,a1,b1,c1);  
    line(q1,q2,a2,b2,c2);
    c1 = -c1;  c2 = -c2;
    double D = (a1 * b2 - a2 * b1);  if (D == 0) return point(inf,inf);
    double Dx = (b2 * c1 - b1 * c2),Dy = (a1 * c2 - a2 * c1);
    return point(Dx/D,Dy/D);
}

int cross_product(point p,point q,point r)
{
    double x1 = q.x - p.x,x2 = r.x - q.x,y1 = q.y - p.y,y2 = r.y - q.y;
    double ans = x1 * y2 - x2 * y1;
    if (abs(ans) < eps) return 0;
    if (ans > eps) return 1;
    return -1;
}

bool allleft(vector<point> v,point p)
{
    if (p.x >= inf) return false;
    for (int i = 0; i < v.size(); i++)
      if (cross_product(v[i],v[(i + 1) % v.size()],p) < 0) return false;
    return true;
}

bool valid(vector<point> v)
{
    if (v.size() < 4) return true;  
    v = redirect(v); 
    for (int i = 0; i < v.size(); i++) if (allleft(v,v[i])) return true;
    for (int i = 0; i < v.size(); i++)
      for (int j = 0; j < v.size(); j++) if (j != i)
          {
                point p = intersect(v[i],v[(i + 1) % v.size()],v[j],v[(j + 1) % v.size()]);
                if (allleft(v,p)) return true;
            }
    return false;
}

int main()
{
//    freopen("stars.inp","r",stdin);
//    freopen("stars.out","w",stdout);
    int n,cnt = 0;
    while (1)
    {
        scanf("%d", &n);
        if (!n) return 0;
        vector<point> v;        
        for (int i = 0; i < n; i++)
        {
            double lx,ly;  scanf("%lf %lf", &lx, &ly);  v.push_back(point(lx,ly));
        }
        printf("%d\n", valid(v));
    }
}

Code mẫu của khuc_tuan

import java.io.*;
import java.util.*;
import static java.lang.Integer.parseInt;

class Process {

    double[] X, Y;
    int n;
    double SSS;

    double sPoly(double[] x,double[] y) {
        double result=0;
        int n = x.length;
        for(int i=0;i<n;++i) {
            result += (x[i]+x[(i+1)%n])*(y[i]-y[(i+1)%n]);
        }
        return Math.abs(result)/2;
    }

    boolean testOk(double x, double y) {
        double result=0;
        for(int i=0;i<n;++i) {
            result += sPoly( new double[]{x,X[i],X[(i+1)%n]}, new double[]{y,Y[i],Y[(i+1)%n]} );
        }
        if(Math.abs(result - SSS) < 1e-5) return true;
        return false;
    }

    boolean giaodiem(double x1,double y1,double x2,double y2,double x3,double y3, double x4,double y4,double[] res) {
        double a1,b1,c1,a2,b2,c2,dt;
        a1 = y1-y2;
        b1 = x2-x1;
        c1 = x1*(y1-y2)-y1*(x1-x2);

        a2 = y3-y4;
        b2 = x4-x3;
        c2 = x3*(y3-y4)-y3*(x3-x4);

        dt = a1*b2-a2*b1;
        if(Math.abs(dt)<1e-5) return false;
        res[0] = (c1*b2-c2*b1)/dt;
        res[1] = (a1*c2-a2*c1)/dt;
        return true;
    }

    boolean checkPoly(int[] _X,int[] _Y) {
        n=_X.length;
        X=new double[n];
        Y=new double[n];
        for(int i=0;i<n;++i) {
            X[i] = _X[i];
            Y[i] = _Y[i];
        }
        SSS = sPoly(X, Y);
        double[] a=new double[2];
        for(int i=0;i<n;++i) for(int j=i+1;j<n;++j) 
            if(giaodiem(X[i],Y[i],X[(i+1)%n],Y[(i+1)%n],X[j],Y[j],X[(j+1)%n],Y[(j+1)%n],a)) {
                if(testOk(a[0],a[1])) return true;
            }
        return false;
    }
}

public class Main {
    public static void main(String[] Args) throws Exception {
        BufferedReader kb=new BufferedReader(new InputStreamReader(System.in));
        while(true) {
            int n = parseInt(kb.readLine());
            if(n==0) break;
            int[] x,y;
            x=new int[n];
            y=new int[n];
            for(int i=0;i<n;++i) {
                String[] tam=kb.readLine().split(" ");
                x[i]=parseInt(tam[0]);
                y[i]=parseInt(tam[1]);
            }
            if(new Process().checkPoly(x,y)) System.out.println(1);
            else System.out.println(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.