No.96 圏外です。 - yukicoder
- バケット法 + union find + convex hull + キャリパー法。
- バケット法以外は思いついた。無駄に kd 木とかないとダメなのかなぁと思っていたらバケット法でよかった。バケット法の実装は初めてなので勉強になった。
- x,y の制約を Easy のままにしていて RE してしまった。
- 下のコードにはないが自作の Pt class (点表現クラス) の operator < の実装をミスって、std::sort で segv してしまった。
- std::sort に渡す less は a < b じゃないとダメってやつ。(a <= b じゃダメ) わりと有名なアレ。
class NoService {
public:
void solve(void) {
int N;
cin>>N;
if (N==0)
{
cout<<1<<endl;
return;
}
UFTree uft(N);
const int offset = 10000;
const int B = 10;
const int dx[] = {-1,0,1};
const int dy[] = {-1,0,1};
const int M = 2*offset/B;
vector<vector<vector<int>>> bucket(M+1,vector<vector<int>>(M+1, vector<int>()));
vector<Pt<int>> ps;
REP(i,N)
{
int x,y;
cin>>x>>y;
ps.emplace_back(x,y);
bucket[(x+offset)/B][(y+offset)/B].push_back(i);
}
REP(i,N)
{
int xi = (ps[i].x+offset)/B;
int yi = (ps[i].y+offset)/B;
REP(ii,3)
REP(jj,3)
{
int xi2 = xi+dx[ii];
int yi2 = yi+dy[jj];
if (xi2 < 0 || xi2 > M || yi2 < 0 || yi2 > M)
continue;
for (auto k : bucket[xi2][yi2])
{
if (k == i)
continue;
if ( (ps[k]-ps[i]).norm() <= 10 )
uft.unite(k,i);
}
}
}
vector<vector<Pt<int>>> group(N);
REP(i,N)
group[uft[i]].push_back(ps[i]);
double ans = 0;
REP(i,N)
{
if (uft[i]==i)
ans = max(ans, Pt<int>::convex_diameter(group[uft[i]]));
}
cout<<setprecision(20)<<ans+2<<endl;
}
};