AOJ 580 Fish (おそらく非想定解?)
AOJで他の解法投げると見れなくなると思うので,とりあえずコード貼っておきます
解法
直方体とその領域で重なっている数を持っておく.
ソースコード
struct Rect { int v[3][2]; ll calc_area() const { ll res = 1; rep(d, 3) res *= v[d][1] - v[d][0]; return res; } }; typedef pair<Rect, int> Area; // (rect, num of fishes) bool intersect(const Rect& a, const Rect& b, Rect& r) { rep(d, 3) { r.v[d][0] = max(a.v[d][0], b.v[d][0]); r.v[d][1] = min(a.v[d][1], b.v[d][1]); if (r.v[d][0] >= r.v[d][1]) return false; } return true; } int main() { int n, k; cin >> n >> k; const int inf = ten(8); Rect inf_rect; rep(d, 3) { inf_rect.v[d][0] = -inf; inf_rect.v[d][1] = inf; } vector<Area> area; area.pb(make_pair(inf_rect, 0)); rep(fi, n) { Rect fish; rep(i, 2) rep(d, 3) cin >> fish.v[d][i]; vector<Area> narea; foreach (it, area) { Rect and_rect; if (intersect(fish, it->first, and_rect)) { narea.pb(make_pair(and_rect, it->second + 1)); int bound[3][4]; rep(d, 3) { bound[d][0] = -inf; bound[d][1] = and_rect.v[d][0]; bound[d][2] = and_rect.v[d][1]; bound[d][3] = inf; } rep(i, 3) rep(j, 3) rep(k, 3) { if (i == 1 && j == 1 && k == 1) { // excluding: temp_rect == and_rect continue; } Rect temp_rect; temp_rect.v[0][0] = bound[0][i]; temp_rect.v[0][1] = bound[0][i + 1]; temp_rect.v[1][0] = bound[1][j]; temp_rect.v[1][1] = bound[1][j + 1]; temp_rect.v[2][0] = bound[2][k]; temp_rect.v[2][1] = bound[2][k + 1]; Rect and_r; if (intersect(temp_rect, it->first, and_r)) narea.pb(make_pair(and_r, it->second)); } } else narea.pb(*it); } area = narea; } ll res = 0; foreach (it, area) if (it->second >= k) res += it->first.calc_area(); cout << res << endl; }