版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36172505/article/details/81568695
题目链接:
UVALive-7825
题目大意:
给你n个不同类型的点的坐标,求不同类型点之间最大距离为多少?
解题思路:
由于点好多好多,所以之间暴力的话,肯定会TLE!!!
所以我们需要先求出每种类型的凸包(用求凸包算法模板就好了),这样可以减少一些点之间距离的计算。
此时如果我们直接拿两个凸包中的点两两去求距离,然后取最大,发现还是会TLE!!!
因此我们需要继续减少不必要的点与点之间的距离计算。
当我们求完凸包A和凸包B之间的最大距离后,把凸包A和凸包B合并成一个新的凸包,然后新凸包继续和后面类型的凸包求最大距离,依次循环,不断更新最大距离
emmmm,曾经尝试过用旋转卡壳来求凸包之间的最大距离,但是老是WA,这题折腾了好多天,可以看一下我的血泪史!!!
最后终于AC了,不说了,都是泪,写到自闭
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int MAXN = 1e5+7;
struct Points{
int x,y;
Points(){}
Points(int x,int y):x(x),y(y){}
Points operator +(const Points &p){
return Points(x+p.x,y+p.y);
}
Points operator -(const Points &p){
return Points(x-p.x,y-p.y) ;
}
Points operator *(const int &d){
return Points(x*d,y*d);
}
bool operator <(const Points &p){
return x==p.x?y<p.y:x<p.x;
}
};
vector<Points> PP[105],ch[105];
int flag[105];
int Cross(Points A,Points B){
return A.x*B.y-A.y*B.x;
}
//??
int cross(Points A,Points B,Points C){
return (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);
}
void ConvexHull (vector<Points> &p,int ty){
sort(p.begin(),p.end());
int m=0;
for(int i=0; i<p.size(); ++i){
while(m>1&&Cross(ch[ty][m-1]-ch[ty][m-2],p[i]-ch[ty][m-2])<=0) {
ch[ty].pop_back();
m=ch[ty].size();
}
ch[ty].push_back(p[i]);
m=ch[ty].size();
}
int k=ch[ty].size();
for(int i=p.size()-2;i>=0;--i){
while(m>k&&Cross(ch[ty][m-1]-ch[ty][m-2],p[i]-ch[ty][m-2])<=0) {
ch[ty].pop_back();
m=ch[ty].size();
}
ch[ty].push_back(p[i]);
m=ch[ty].size();
}
}
int Getdist(Points A,Points B){
return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}
int Maxdist(vector<Points>& P,vector<Points>& Q){
int ret=0;
int len1=P.size();
if(len1>1) len1--;
int len2=Q.size();
if(len2>1) len2--;
for(int i=0; i<len1; ++i){
for(int j=0; j<len2; ++j){
ret=max(ret,Getdist(P[i],Q[j]));
}
}
return ret;
}
void init(){
memset(flag,0,sizeof(flag));
for(int i=0; i<105; ++i){
PP[i].clear();
ch[i].clear();
}
}
int n;
int main(){
cin.sync_with_stdio(false);
while(scanf("%d",&n)&&n){
init();
for(int i=1; i<=n; ++i){
int x,y,t;
scanf("%d%d%d",&x,&y,&t);
flag[t]=1;
Points p(x,y);
PP[t].push_back(p);
}
for(int i=0; i<100; ++i){
if(flag[i]){
ConvexHull(PP[i],i);
// for(int j=0; j<ch[i].size(); ++j) cout<<ch[i][j].x<<" "<<ch[i][j].y<<endl;
}
}
int ans=0,t=0;
for(int i=0; i<100; ++i){
if(flag[i]){
t=i;
break;
}
}
for(int j=0; j<100; ++j){
if(t!=j&&flag[j]){
ans=max(ans,Maxdist(ch[t],ch[j]));
for(int i=0; i<PP[j].size(); ++i) PP[t].push_back(PP[j][i]);
ch[t].clear();
ConvexHull(PP[t],t);
}
}
printf("%d\n",ans);
}
return 0;
}