zoukankan      html  css  js  c++  java
  • [Noip模拟赛] Polygon

    POLYGON

    源程序名 POLYGON.??? (PAS,C,CPP)

    可执行文件名   POLYGON.EXE

    输入文件名     POLYGON.IN

    输出文件名     POLYGON.OUT

       

    对于一个多边形来说,在该多边形内任取两点,如果这两点连成的线段落在多边形内,则称这样的多边形为凸多边形。

    平面上有N个坐标值为自然数的圆点。顶点数最多凸多边形是指由给定的圆点中的一部分组成的凸多边形,它包含最大可能的顶点数。原点,即坐标内中心(0,0)必须是顶点数最多凸多边形的一个顶点。

    编写程序求出这样的凸多边形的最大顶点数。注意一个多边形的连续的边不能是平行的。

    输入

    输入文件的第一行包含一个自然数N,2≤N≤100,表示给定的圆点数。

    下面的N行每行包含两个用空格隔开的自然数X和Y,1≤X≤100,1≤Y≤100,表示一个圆点的坐标值。所有的圆点是不相同的。

    输出

    输出文件的第一行也是唯一的一行应该包含顶点数最多凸多边形的顶点数。注意结果应不小于3。

    样例

    POLYGON.IN

    8

    10 8

    3 9

    2 8

    2 3

    9 2

    9 10

    10 3

    8 10

    POLYGON.OUT

    8

    【题解】

    有点坑。。第一眼看成求凸包顶点数了结果竟然还有50分= =

    然后后面想了半天不会做

    然后呢想了半天发现设f[i,j]表示最后两个点为i和j的情况下凸多边形最大顶点数

    那么枚举k [1...i-1]即可,f[i,j]即可用f[k,i]更新

    更新的情况当且仅当是个凸多边形(用向量叉积判断)

     1 #include <stdio.h>
     2 using namespace std;
     3 struct P {
     4     int x,y;
     5 }p[105];
     6 int n;
     7 int f[105][105];
     8 // f i,j 表示凸多边形的最后两个顶点为i,j所构成的最多顶点数 
     9 inline void IO() {
    10     freopen("polygon.in","r",stdin);
    11     freopen("polygon.out","w",stdout);
    12 }
    13 inline int max(int a,int b) {return a<b?b:a;}
    14 inline void swap(P &a, P &b) {
    15     int _tem;
    16     _tem=a.x, a.x=b.x, b.x=_tem;
    17     _tem=a.y, a.y=b.y, b.y=_tem;
    18 }
    19 inline int cj(P a, P b) {
    20     return a.x*b.y-b.x*a.y;
    21 }
    22 
    23 inline void RS() {
    24     p[0].x=0, p[0].y=0;
    25     scanf("%d",&n);
    26     for (int i=1;i<=n;++i) scanf("%d %d",&p[i].x,&p[i].y);
    27     //按照斜率排序 
    28     for (int i=1;i<n;++i) for (int j=i+1;j<=n;++j)
    29         if (p[i].x*p[j].y < p[j].x*p[i].y)  // y1/x1 > y2/x2
    30             swap(p[i],p[j]);
    31     for (int i=1;i<=n;++i) f[0][i]=1;
    32     for (int i=1;i<=n;++i)
    33         for (int j2=i+1;j2<=n+1;++j2)
    34             for (int k=0;k<=i-1;++k) {
    35                 int j;
    36                 P _x, _y; int _tem;
    37                 if (j2==n+1) j=0;
    38                 else j=j2;
    39                 _x.x=p[i].x-p[k].x, _x.y=p[i].y-p[k].y;
    40                 _y.x=p[j].x-p[i].x, _y.y=p[j].y-p[i].y;
    41                 int c = cj(_y,_x);
    42                 if (c<0) f[i][j]=max(f[i][j],f[k][i]+1); 
    43             }
    44     int ans=0;
    45     for (int i=0;i<=n;++i)
    46         for (int j2=i+1;j2<=n+1;++j2) {
    47             int j;
    48             if (j2==n+1) j=0; else j=j2;
    49             ans = max(ans,f[i][j]);                
    50         }
    51     printf("%d
    ",ans);    
    52 }
    53 int main() {
    54     IO(),
    55     RS();
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    北风设计模式课程---单一职责原则
    北风设计模式课程---访问者模式(Visitor)
    北风设计模式课程---访问者(Visitor)模式
    北风设计模式课程---命令模式
    社交专题---3、装逼的那些事儿
    社交专题---2、男生的套路有多深
    MHA 日常管理
    【屌丝程序的口才逆袭演讲稿50篇】第十篇:程序猿们请看看外面的世界吧【张振华.Jack】
    Win32 Windows编程 九
    java实现大数相加问题
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/noip_polygon.html
Copyright © 2011-2022 走看看