結果

問題 No.96 圏外です。
ユーザー motxx
提出日時 2014-12-09 03:50:49
言語 C++11(廃止可能性あり)
(gcc 13.3.0)
結果
AC  
実行時間 1,262 ms / 5,000 ms
コード長 4,588 bytes
コンパイル時間 1,924 ms
コンパイル使用メモリ 177,288 KB
実行使用メモリ 22,480 KB
最終ジャッジ日時 2024-12-24 08:01:29
合計ジャッジ時間 8,414 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 28
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
typedef double Real;
// typedef long double Real;
typedef complex<Real> P;
namespace std {
bool operator < (P const& a, P const& b) {
return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
}
Real dot(P const& a, P const& b) {
return real(conj(a)*b);
}
Real cross(P const& a, P const& b) {
return imag(conj(a)*b);
}
enum { counter_clockwise=+1, clockwise=-1, cab_online=+2, abc_online=-2, on_segment = 0 };
int ccw(P a, P b, P c) {
b -= a; c -= a;
if(cross(b, c) > 0) return counter_clockwise;
if(cross(b, c) < 0) return clockwise;
if(dot(b, c) < 0) return cab_online;
if(norm(b) < norm(c)) return abc_online;
return on_segment;
}
typedef vector<P> Polygon;
#define prev(G, i) ( G[(i-1 + G.size()) % G.size()] )
#define curr(G, i) ( G[i % G.size()] )
#define next(G, i) ( G[(i+1) % G.size()] )
Polygon convex_hull(vector<P> ps) {
int n = ps.size(), k = 0;
sort(ps.begin(), ps.end());
vector<P> ch(2*n);
for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
ch.resize(k-1);
return ch;
}
Real convex_naive_diameter(Polygon const& g) {
int N = g.size();
Real ret = 0.;
rep(i, N) REP(j, i, N) {
ret = max(ret, abs(g[i]-g[j]));
}
return ret;
}
#define diff(G, i) (next(G, i) - curr(G, i))
// O(n)
Real convex_diameter(Polygon const& g) {
int const N = g.size();
int is = 0, js = 0;
REP(i, 1, N) {
if(imag(g[i]) > imag(g[is])) { is = i; }
if(imag(g[i]) < imag(g[js])) { js = i; }
}
Real mxd = norm(g[is]-g[js]);
int i, mxi, j, mxj;
i = mxi = is;
j = mxj = js;
do {
if(cross(diff(g, i), diff(g, j)) >= 0) { j = (j+1) % N; }
else { i = (i+1) % N; }
if(norm(g[i]-g[j]) > mxd) {
mxd = norm(g[i]-g[j]);
mxi = i, mxj = j;
}
} while(i != is || mxj != js);
return mxd;
}
inline bool inrange(int x, int y, int W, int H) {
return 0<=x&&x<W&&0<=y&&y<H;
}
struct UnionFind
{
vector<int> rank;
vector<int> par;
UnionFind(int n) {
rank.resize(n), par.resize(n);
rep(i, n) { par[i] = i; rank[i] = 0; }
}
int find(int x) {
if(par[x] == x) { return x; }
else { return par[x] = find(par[x]); }
}
void unite(int x, int y) {
x = find(x), y = find(y);
if(x == y) { return; }
if(rank[x] < rank[y]) { par[x] = y; }
else {
par[y] = x;
if(rank[x] == rank[y]) { rank[x] ++; }
}
}
bool same(int x, int y) {
return find(x) == find(y);
}
};
vector<P> ps;
int constexpr Offset = 10000;
int constexpr MaxSize = 21000;
int constexpr BSize = 50;
vector<int> bucket[MaxSize/BSize][MaxSize/BSize];
int main() {
int N; cin >> N;
if(N == 0) { cout << 1 << endl; return 0; }
//if(N == 1) { cout << 10 << endl; return 0; }
rep(i, N) {
double x, y; cin >> x >> y;
//cerr << x << ", " << y << " " << Offset << endl;
ps.push_back(P(x+Offset, y+Offset));
}
/*
if(N == 2) {
if(abs(ps[0]-ps[1]) <= 10.) {
cerr << ps[0] << " " << ps[1] << endl;
cerr << abs(ps[0]-ps[1]) << endl;
printf("%.10f\n", abs(ps[0]-ps[1])+10); return 0;
}
}
*/
rep(i, N) {
int bx = ps[i].real()/BSize;
int by = ps[i].imag()/BSize;
bucket[by][bx].push_back(i);
}
UnionFind uf(2*N);
rep(i, N) {
int bx = ps[i].real()/BSize;
int by = ps[i].imag()/BSize;
REP(outy, -1, 2) REP(outx, -1, 2) {
int x = bx+outx, y = by+outy;
if(inrange(x, y, MaxSize/BSize, MaxSize/BSize)) {
for(auto j: bucket[y][x]) {
//cerr << "bucket: " << x << ", "<< y << endl;
//cerr << "ps: " << i << ", " << j << endl;
if(abs(ps[i]-ps[j]) <= 10.) { uf.unite(i, j); }
}
}
}
}
vector<vector<P> > clusters(N);
rep(i, N) {
clusters[uf.find(i)].push_back(ps[i]);
}
Real ans = 0.;
for(auto& g: clusters) {
if(g.empty()) { continue; }
//Real dia = convex_diameter(g);
g = convex_hull(g);
Real dia = convex_naive_diameter(g);
ans = max(ans, dia+2);
}
printf("%.10f\n", ans);
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0