JOI2008 春合宿 Cheating
問題ページ
http://www.ioi-jp.org/camp/2008/2008-sp-tasks/2008-sp_tr-day2_21.pdf
考えたこと
最大の最小化と言われたので二分探索をする。幅Xで実現することができるかの判定について考える。x方向、y方向についてそれぞれ貪欲に決めていくと幅Xで必要なカメラの台数をO(M)で判定できる。したがってO(Mlog(max(X,Y)))で解くことができ間に合う。
//#define __USE_MINGW_ANSI_STDIO 0 #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> VI; typedef vector<VI> VVI; typedef vector<ll> VL; typedef vector<VL> VVL; typedef pair<int, int> PII; #define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i) #define REP(i, n) FOR(i, 0, n) #define ALL(x) x.begin(), x.end() #define IN(a, b, x) (a<=x&&x<b) #define MP make_pair #define PB push_back const int INF = (1LL<<30); const ll LLINF = (1LL<<60); const double PI = 3.14159265359; const double EPS = 1e-12; const int MOD = 1000000007; //#define int ll template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); } template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); } int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; int n, m; VI x, y; bool check(ll mid) { int tmp = 0; // x方向 int i = 0; while(i < (int)x.size()) { int st = i; while(i < (int)x.size() && x[i] - x[st] <= mid) ++i; ++tmp; } // y方向 i = 0; while(i < (int)y.size()) { int st = i; while(i < (int)y.size() && y[i] - y[st] <= mid) ++i; ++tmp; } if(tmp <= n) return true; return false; } signed main(void) { cin >> n >> m; REP(i, m) { int xx, yy; cin >> xx >> yy; x.PB(xx); y.PB(yy); } sort(ALL(x)); x.erase(unique(ALL(x)), x.end()); sort(ALL(y)); y.erase(unique(ALL(y)), y.end()); // (low, high] ll low = -1, high = 1000000000; while(high-low>1) { ll mid = (low+high)/2; if(check(mid)) { high = mid; } else { low = mid; } } cout << high << endl; return 0; }