团体程序设计天梯赛(CCCC) L3012 水果忍者 上凸或下凹的证明
团体程序设计天梯赛代码。体现代码技巧,比赛技巧。 https://github.com/congmingyige/cccc_code
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 */