SRM411: HoleCakeCuts

(問題概要)
回 ← みたいなケーキがある(真ん中に穴が空いてる)
縦と横にそれぞれ何回か包丁を入れた時に、最終的に何ピースのケーキが出来るか。

(解法)
縦横で近いカットを2つづつ選ぶとそれに囲まれた四角形ができる。
後はその頂点を見て場合分け。
関数名がクソ命名。

#include <cstdio>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

#include <algorithm>
#include <queue>
#include <set>
#include <iostream>
#include <sstream>

using namespace std;

class HoleCakeCuts {
public:
  int cutTheCake(int cakeLength, int holeLength, vector <int> horizontalCuts, vector <int> verticalCuts);
};

inline bool isHole(int h, int w, int hl){
  return std::abs(w) <= hl && std::abs(h) <= hl;
}

inline bool overHole(int h1, int h2, int hl){
  return h1 < -hl && hl < h2;
}

inline bool onHole(int h1, int h2, int hl){
  return isHole(h1, 0, hl) && isHole(h2, 0, hl);
}

int HoleCakeCuts::cutTheCake(int cl, int hl, vector <int> h, vector <int> v){
  int cnt = 0;

  h.push_back(cl);
  h.push_back(-cl);
  v.push_back(cl);
  v.push_back(-cl);

  sort(h.begin(), h.end());
  sort(v.begin(), v.end());

  REP(i,h.size() - 1) REP(j,v.size() - 1){
    const int h1 = h[i];
    const int h2 = h[i + 1];
    const int v1 = v[j];
    const int v2 = v[j + 1];

    const bool hole1 = isHole(h1, v1, hl);
    const bool hole2 = isHole(h2, v2, hl);

    if(!hole1 && !hole2){
      const bool over1 = overHole(h1, h2, hl);
      const bool over2 = overHole(v1, v2, hl);

      const bool on1 = onHole(h1, h2, hl);
      const bool on2 = onHole(v1, v2, hl);

      if((over1 && on2) || (over2 && on1)) cnt++;
      cnt++;
    }else if(!hole1 || !hole2){
      cnt++;
    }
  }

  return cnt;
}