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; }