## 团体程序设计天梯赛(CCCC) L3012 水果忍者 上凸或下凹的证明

```  1 #include <cstdio>
2 #include <cstdlib>
3 #include <cmath>
4 #include <cstring>
5 #include <algorithm>
6 using namespace std;
7
8 #define ll long long
9 const int maxn=1e4+10;
10 const int inf=1e9;
11 const double eps=1e-8;
12
13 struct node
14 {
15     int x,y;
16 }d1[maxn],d2[maxn],a[maxn];
17
18 ll cross(node c,node a,node b)
19 {
20     ///两者相乘，也许大于int范围
21     return 1ll*(c.y-a.y)*(c.x-b.x) - 1ll*(c.x-a.x)*(c.y-b.y);
22 }
23
24 bool cmp1(node a,node b)
25 {
26     ll v=cross(d1[1],a,b);
27     if (v==0)
28         return d1[1].x-a.x<d1[1].x-b.x;
29     return v<0;
30 }
31
32 bool cmp2(node a,node b)
33 {
34     ll v=cross(d2[1],a,b);
35     if (v==0)
36         return d2[1].x-a.x<d2[1].x-b.x;
37     return v>0;
38 }
39
40 /**
41 两者在v==0处无法统一
42 **/
43
44 int main()
45 {
46     int n,x,ymax,ymin,i,j,ind=0,m;
47     double k,b;
48     d1[0].x=inf;
49     scanf("%d",&n);
50     for (i=1;i<=n;i++)
51     {
52         scanf("%d%d%d",&x,&ymax,&ymin);
53         d1[i]={x,ymax},d2[i]={x,ymin};
54         if (d1[i].x<d1[ind].x)
55             ind=i;
56     }
57
58     if (n==1)
59     {
60         printf("%d %d %d %d",-1,ymax,0,ymax);
61         return 0;
62     }
63
64     swap(d1[1],d1[ind]);
65     sort(d1+2,d1+n+1,cmp1); ///注意是+2(对d1[2]~d1[n]排序)
66     m=0;
67     for (i=1;i<=n;i++)
68     {
69         while (m>=2 && cross(a[m],a[m-1],d1[i])<=0)
70             m--;
71         a[++m]=d1[i];
72     }
73
74     for (i=2;i<=m;i++)
75     {
76         if (a[i].x<a[i-1].x)
77             break;
78         k=1.0*(a[i].y-a[i-1].y)/(a[i].x-a[i-1].x);
79         b=a[i].y-k*a[i].x;
80         for (j=1;j<=n;j++)
81             if (k*d2[j].x+b<d2[j].y-eps)
82                 break;
83         if (j==n+1)
84         {
85             printf("%d %d %d %d",a[i].x,a[i].y,a[i-1].x,a[i-1].y);
86             return 0;
87         }
88     }
89
90     swap(d2[1],d2[ind]);
91     sort(d2+2,d2+n+1,cmp2);
92     m=0;
93     for (i=1;i<=n;i++)
94     {
95         while (m>=2 && cross(a[m],a[m-1],d2[i])>=0)
96             m--;
97         a[++m]=d2[i];
98     }
99     for (i=2;i<=m;i++)
100     {
101         if (a[i].x<a[i-1].x)
102             break;
103         k=1.0*(a[i].y-a[i-1].y)/(a[i].x-a[i-1].x);
104         b=a[i].y-k*a[i].x;
105         for (j=1;j<=n;j++)
106             if (k*d1[j].x+b>d1[j].y+eps)
107                 break;
108         if (j==n+1)
109         {
110             printf("%d %d %d %d",a[i].x,a[i].y,a[i-1].x,a[i-1].y);
111             return 0;
112         }
113     }
114
115     return 0;
116 }
117 /*
118 4
119 -1 5 3
120 2 4 3
121 1 5 2
122 0 4 3
123 */```

0条评论