1 /*LA 4728
2 凸包算法-旋转卡壳的直径
3 没有其他技巧,可作为模板运用
4 注意operator< 中精度的处理,不然会出错
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <math.h>
10 #include <ctype.h>
11 #include <string>
12 #include <iostream>
13 #include <sstream>
14 #include <vector>
15 #include <queue>
16 #include <stack>
17 #include <map>
18 #include <list>
19 #include <set>
20 #include <algorithm>
21 #define INF 0x3f3f3f3f
22 #define LL long long
23 #define eps 1e-7
24 #define maxn 401000
25 using namespace std;
26
27
28 struct Point
29 {
30 double x,y;
31 Point() {}
32 Point(LL xx,LL yy)
33 {
34 x=xx+0.0;
35 y=yy+0.0;
36 }
37 bool operator<(const Point& p) const//注意:按照逆时针旋转
38 {
39 if (fabs(x-p.x)<eps) return y<p.y;//注意,这里eps一定要加,不然,不能正常排序
40 else return x<p.x;
41 }
42 } P1[maxn],P2[maxn];
43
44 typedef Point Vector;
45
46 bool operator==(Point A,Point B)
47 {
48 if ((fabs(A.x-B.x)<eps) && (fabs(A.y-B.y)<eps)) return true;
49 else return false;
50 }
51 Vector operator-(Point A,Point B)//表示A指向B
52 {
53 return Vector(A.x-B.x,A.y-B.y);
54 }
55 Vector operator*(Vector A,double k)
56 {
57 return Vector(A.x*k,A.y*k);
58 }
59 Vector operator+(Point A,Point B)//表示A指向B
60 {
61 return Vector(B.x+A.x,B.y+A.y);
62 }
63 double Cross(Vector A,Vector B)
64 {
65 return A.x*B.y-A.y*B.x;
66 }
67 double Area2(Point A,Point B,Point C)
68 {
69 return Cross(B-A,C-A);
70 }
71 //p是原先点的数组,n是个数,ch是凸包的点集
72 //精度要求高是用dcmp比较
73 //返回凸包点的个数
74 int ConvexHull(Point *p, int n, Point* ch) //求凸包
75 {
76 sort(p, p + n);//先按照x,再按照y
77 int m = 0;
78 for(int i = 0; i < n; i++)
79 {
80 while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--;
81 ch[m++] = p[i];
82 }
83 int k = m;
84 for(int i = n-2; i >= 0; i--)
85 {
86 while(m > k && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--;
87 ch[m++] = p[i];
88 }
89 if(n > 1) m--;
90 return m;
91 }
92 //卡壳预备函数
93 LL cross( const Point &o, const Point &a, const Point & b ) {
94 return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
95 }
96 LL dist( const Point & a, const Point & b ) {
97 Point p = a - b;
98 return p.x * p.x + p.y * p.y;
99 }
100 //计算凸包直径,输入凸包 ch,顶点个数为 n,按逆时针排列,输出直径的平方
101 LL rotating_calipers(Point *ch,int n)
102 {
103 LL q=1,ans=0;
104 ch[n]=ch[0];
105 for(int p=0; p<n; p++)
106 {
107 while(cross(ch[p],ch[p+1],ch[q+1])>cross(ch[p],ch[p+1],ch[q]))
108 q=(q+1)%n;
109 ans=max(ans,max(dist(ch[p],ch[q]),dist(ch[p+1],ch[q+1])));
110 }
111 return ans;
112 }
113 int t,n,cnt1,cnt2;
114 int main()
115 {
116 cin>>t;
117 while(t--)
118 {
119 cnt1=0;
120 cin>>n;
121 for(int i=0;i<n;i++)
122 {
123 LL x,y,w;
124 cin>>x>>y>>w;
125 P1[cnt1++]=Point(x,y);
126 P1[cnt1++]=Point(x+w,y);
127 P1[cnt1++]=Point(x,y+w);
128 P1[cnt1++]=Point(x+w,y+w);
129 }
130 cnt2=ConvexHull(P1,cnt1,P2);
131 cout<<rotating_calipers(P2,cnt2)<<endl;
132 }
133 return 0;
134 }