GCJに向けて本気で問題を解説してみる 第4回 (Get Many Persimmon Trees)

第4回の今回も少し飛びまして「Get Many Persimmon Trees」という問題を解説したいと思います。参考ページは以下の通り。

「ACM/ICPC国内予選突破の手引き」
「AOJの問題ページ」


さてこの問題では次のような条件が与えられています。

  • W×Hのフィールドに柿の木 (Persimmon Tree) が何本か生えている
  • そのフィールド内に大きさS×Tの領地がもらえることになった
  • 柿の木の数が最大になるような領地の取り方が知りたい

この問題も効率よくやろうとすると大変そうな気がしますが、計算量は高々$10^8$以下であり、十分に単純な探索で解くことができます。


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <queue>
#include <string>
using namespace std;

#define rep(i,n) for(int i=0; i<n; i++)
#define repa(i,s,e) for(int i=s; i<=e; i++)
#define repd(i,s,e) for(int i=s; i>=e; i--)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef pair<int, int> pii;

int N, W, H;
int x, y;
int S, T;
char F[501][501];

int main() {
    while(cin >> N, N) {
        cin >> W >> H;
        memset(&F[0][0], 0, sizeof(char) * 501 * 501);

        rep(i,N) {
            cin >> x >> y;
            F[x][y] = 1;
        }
        cin >> S >> T;

        int mt = 0;
        repa(j,1,H-T+1) {
            repa(i,1,W-S+1) {
                int t = 0;
                rep(l,T) {
                    rep(k,S) {
                        if(F[i+k][j+l]) t++;
                    }
                }

                if(mt < t) {
                    mt = t;
                }
            }
        }

        cout << mt << endl;
    }
}