Problem:
コンビニ
コンビニエンスストア・デブンイレブンは事業を広げるため若松市に一店舗目をオープンしようと考えています。若松市には既に他のたくさんのコンビニエンスストアがあるので、新店舗をオープンする場所が成功の鍵を握ることになりそうです。デブンイレブンは「お客さんは自分の住んでいる地域から最も近いコンビニを利用する」という前提の下、「多くのお客さんが利用するであろう地点」に出店することにしています。
デブンイレブンは、既設の各コンビニがカバーしている範囲を把握するため、若松市の地図を合同な正六角形(以後「ブロック」)を用いて区分しました。このとき、各ブロックには既設のコンビニが多くとも一つだけ入るように区分しました。この地図上で、各ブロックからあるコンビニへ行くのに経由するブロックの数をもとにコンビニとの距離を求めます。各ブロックはこの距離が最も小さいコンビニによってカバーされていると考えます。問題は、この地図をもとに「できるだけ多くのブロックをカバーする既設のコンビニがないブロック」を探すことです。
デブンイレブンのプログラマであるあなたは、ブロック分けされた地図情報と新店舗の候補地の情報から、最も広くカバーできるブロック数を計算するプログラムを開発することになりました。
m × n
に区分した地図は図1のように表します。六角形のブロックが横に
m
個、縦に
n
個並び、それぞれは一つの座標(
x, y
)で示されます。奇数行の左端はその上の行の左端の左下に、偶数行の左端はその上の行の左端の右下に、それぞれ位置します。例えば、座標(1, 1)は図1の一番左上のブロックを示します。また、座標(1, 2)は座標(1, 1)の右下に位置し、座標(1, 3)は座標(1, 2)の左下に位置します。
図2は既設のコンビニが6個あった場合の例で、6 × 6 に区分されています。各コンビニは1から順に番号が振られています。このとき、各コンビニがカバーするブロックを番号毎に塗り分けると図3のようになります。座標(1, 4)や(2, 5)のように塗られていないブロックは最も近いコンビニが二つ以上あり、どちらとも判断がつかないブロックになっています。例えば、座標(1, 4)のブロックの場合、番号4のコンビニと番号5のコンビニへの距離が等しく、このブロックをカバーしているコンビニはないものとして考えます。番号4のコンビニがカバーしているブロック数は5となります。
ここで、デブンイレブンが座標(1, 3)と座標(5, 3)を新店舗の候補地として考えているとします。座標(1, 3)に店舗を構えた場合、カバーできるブロック数は3となります(図4)。一方、座標(5, 3)に店舗を構えた場合にカバーできるブロック数は4となります(図5)。したがって、最も広くカバーできるブロック数は4となります。
地図情報
m × n
、既設のコンビニの数
s
とその座標(
x, y
)、候補地の数
t
とその座標(
p, q
)を入力とし、全候補地の中で最も広くカバーできるブロック数を出力するプログラムを作成してください。
Input
複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。 各データセットは以下の形式で与えられます。
m
n
s
x
1
y
1
x
2
y
2
:
x
s
y
s
t
p
1
q
1
p
2
q
2
:
p
t
q
t
1 行目に区分した地図の大きさ(横、縦)を表す整数
m
,
n
(2 ≤
m, n
≤ 100) が与えられます。
2行目に既設のコンビニの数
s
(1 ≤
s
≤ 10) が与えられます。続く
s
行に、
i
個目の既設のコンビニの座標
x
i
,
y
1
が与えられます。
続く行に、新店舗の候補地の数
t
(1 ≤
t
≤ 10 ) が与えられます。続く
t
行に、
i
個目の候補地の座標
p
i
,
q
i
が与えられます。
データセットの数は 20 を超えません。
Output
データセット毎に、全候補地の中で最も広くカバーできるブロック数を１行に出力します。
Sample Input
6 6
6  
1 1
6 1
3 2
3 5
1 6
5 6
2
1 3
5 3
6 6
6
3 2
3 5
6 1
1 1
1 6
5 6
2
2 3
5 3
0 0
Output for the Sample Input
4
4

Submitted solutions:

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <queue>
using namespace std;

#define INF 1010001000

typedef pair<int, int> i_i;
typedef long long int ll;

int n, m;
int dom[6] = {1, 1, 1, 0, -1, 0};
int don[6] = {-1, 0, 1, -1, 0, 1};
int dem[6] = {-1, -1, -1, 0, 1, 0};
int den[6] = {-1, 0, 1, -1, 0, 1};

int bfs(int x, int y, vector<vector<int> > &g, vector<vector<bool> > &pos);
int solve(int x,int y, vector<vector<int> > &g, vector<vector<bool> > &pos);

int main()
{
    while (cin >> m >> n, (n|m)) {
        int s, t;
        vector<vector<int> > g(n, vector<int>(m, 0));
        vector<vector<bool> > pos(n, vector<bool>(m, false));
        cin >> s;
        for (int i = 0; i < s; i++) {
            int x, y;
            cin >> x >> y;
            pos[y-1][x-1] = true;
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                //cout << "===" << i << j << "===" << endl;
                g[i][j] = bfs(i, j, g, pos);
                //cout << g[i][j];
            }
            //cout << endl;
        }
        cin >> t;
        int ans = -INF;
        for (int i = 0; i < t; i++) {
            int x, y;
            cin >> x >> y;
            ans = max(solve(y-1, x-1, g, pos), ans);
        }
        cout << ans << endl;
    }
    return 0;
}

int solve(int x, int y, vector<vector<int> > &g, vector<vector<bool> > &pos)
{
    int ret = 0, dist = 0;
    vector<vector<bool> > ch(n, vector<bool>(m, false));
    queue<i_i> a, b, c;
    a.push(make_pair(x, y));
    while (!a.empty()) {
        while (!a.empty()) {
            i_i tmp = a.front(); a.pop();
            x = tmp.first; y = tmp.second;
            if (ch[x][y]) {
                continue;
            } else {
                ch[x][y] = true;
            }
            if (dist < g[x][y]) {
                ret++;
                for (int i = 0; i < 6; i++) {
                	if (x % 2) {
	                    int nx = x + don[i];
    	                int ny = y + dom[i];
        	            if (0 <= nx && nx < n && 0 <= ny && ny < m) {
            	            b.push(make_pair(nx, ny));
                	    }
                	} else {
	                    int nx = x + den[i];
    	                int ny = y + dem[i];
        	            if (0 <= nx && nx < n && 0 <= ny && ny < m) {
            	            b.push(make_pair(nx, ny));
                	    }                		
                	}
                }
            }
        }
        a = b;
        b = c;
        dist++;
    }
    return ret;
}

int bfs(int x, int y, vector<vector<int> > &g, vector<vector<bool> > &pos)
{
    int ret = 0;
    queue<i_i> a, b, c;
    vector<vector<bool> > ch(n, vector<bool>(m, false));
    a.push(make_pair(x, y));
    while (!a.empty()) {
        while (!a.empty()) {
            i_i tmp = a.front();
            a.pop();
            x = tmp.first;
            y = tmp.second;
            if (ch[x][y]) {
                continue;
            } else {
                ch[x][y] = true;
            }
            if (pos[x][y]) {
                return ret;
            } else {
                for (int i = 0; i < 6; i++) {
                	if (x % 2) {
    	                int nx = x + don[i];
        	            int ny = y + dom[i];
            	        if (0 <= nx && nx < n && 0 <= ny && ny < m) {
                	        b.push(make_pair(nx, ny));
                    	}
                	} else {
    	                int nx = x + den[i];
        	            int ny = y + dem[i];
            	        if (0 <= nx && nx < n && 0 <= ny && ny < m) {
                	        b.push(make_pair(nx, ny));
                    	}
                	}
                }
            }
        }
        ret++;
        a = b;
        b = c;
    }
    return ret;
}
accuracy: 1
time_ms: 270
memory_kb: 3152
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX 110
#define INF (1<<29)
typedef pair<int, int> pii;

int d[11][MAX][MAX]; 

int get_max_block(int M, int N,
                  vector<int> &x, vector<int> &y)
{
    int s = x.size();
    vector<int> cnt(s, 0);
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            int mini = INF, mid = -1, c = -1;
            for (int k = 0; k < s; k++) {
                if (d[k][i][j] < mini) {
                    mini = d[k][i][j];
                    c = 1;
                    mid = k;
                } else if (d[k][i][j] == mini) {
                    c = -1;
                }
            }
            if (c == 1) {
                cnt[mid]++;
            }
        }
    }        
    return cnt[s-1];
}

int get_dist(int sx, int sy, int gx, int gy, int M, int N)
{
    queue<pii> Q;
    Q.push(pii(sx, sy));

    vector<vector<int>> md(MAX, vector<int>(MAX, INF));
    md[sy][sx] = 0;

    const int dx[2][6] = {
        {-1, +0, -1, +1, -1, +0},
        {+0, +1, -1, +1, +0, +1}
    };
    const int dy[6] = {-1, -1, +0, +0, +1, +1};
    
    while (!Q.empty()) {
        pii p = Q.front(); Q.pop();
        int x = p.first, y = p.second;
        if (x == gx && y == gy) {
            return md[y][x];
        }

        for (int i = 0; i < 6; i++) {
            int nx = x + dx[y&1][i];
            int ny = y + dy[i];

            if (0 <= nx && nx < M && 0 <= ny && ny < N) {
                if (md[y][x] + 1 < md[ny][nx]) {
                    md[ny][nx] = md[y][x] + 1;
                    Q.push(pii(nx, ny));
                }
            }
        }        
    }
    return INF;
}

int main()
{
    int M, N, s, t;
    while (cin >> M >> N, M) {
        cin >> s;
        vector<int> x(s), y(s);
        for (int i = 0; i < s; i++) {
            cin >> x[i] >> y[i];
            x[i]--; y[i]--;
            for (int j = 0; j < M; j++) {
                for (int k = 0; k < N; k++) {
                    d[i][j][k] = get_dist(x[i], y[i], j, k, M, N);
                }
            }
        }
        
        int res = 0;
        
        cin >> t;
        for (int i = 0; i < t; i++) {
            int X, Y;
            cin >> X >> Y;
            X--; Y--;
            for (int j = 0; j < M; j++) {
                for (int k = 0; k < N; k++) {
                    d[s][j][k] = get_dist(X, Y, j, k, M, N);
                }
            }
            x.push_back(X); y.push_back(Y);
            res = max(res, get_max_block(M, N, x, y));
            x.pop_back(); y.pop_back();
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3252
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define at(t, i) get<i>(t)
typedef pair<int, int> Pr;
typedef tuple<int, int, int> Tp;
const int INF = 1 << 28;
const int dx[] = {0, -1, -1, 0, 1, 1};
const int dy[][6] = {
	{-1, 0, 1, 1, 1, 0},
	{-1, -1, 0, 1, 0, -1},
};

int m, n;
int s, t;
Pr pos[11];
int dist[11][128][128];

int solve()
{
	fill_n(**dist, 11 * 128 * 128, INF);
	for (int i = 0; i <= s; i++){
		for (int j = 0; j <= 127; j++){
			for (int k = 0; k <= 127; k++){
				if (j == 0 || k == 0 || j == 127 || k == 127){
					dist[i][j][k] = 0;
				}
			}
		}
	}
	
	for (int i = 0; i <= s; i++){
		dist[i][pos[i].first][pos[i].second] = 0;
		queue<Tp> que;
		for (que.push(Tp(pos[i].first, pos[i].second, 0)); que.size(); que.pop()){
			Tp t = que.front();
			int x = at(t, 0);
			int y = at(t, 1);
			int d = at(t, 2);
			//printf("%d %d %d\n", x, y, d);
			if (dist[i][x][y] < d) continue;
			for (int dir = 0; dir < 6; dir++){
				int nx = x + dx[dir];
				int ny = y + dy[x & 1][dir];
				if (dist[i][nx][ny] > d + 1){
					dist[i][nx][ny] = d + 1;
					que.push(Tp(nx, ny, d + 1));
				}
			}
		}
	}
	
	/*for (int i = 0; i <= s; i++){
		for (int j = 1; j <= n; j++){
			for (int k = 1; k <= m; k++){
				printf("%d ", dist[i][j][k]);
			}
			puts("");
		}
		puts("\n");
	}*/
	
	int res = 0;
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			int p = 0;
			for (int k = 1; k <= s; k++){
				if (dist[p][i][j] >= dist[k][i][j]){
					p = k;
				}
			}
			if (p == 0) res++;
		}
	}
	
	return res;
}

int main()
{
	while (scanf("%d %d", &m, &n), m){
		scanf("%d", &s);
		for (int i = 0; i < s; i++){
			int x, y;
			scanf("%d %d", &x, &y);
			pos[i + 1] = Pr(y, x);
		}
		
		int res = 0;
		scanf("%d", &t);
		for (int i = 0; i < t; i++){
			int p, q;
			scanf("%d %d", &p, &q);
			pos[0] = Pr(q, p);
			res = max(res, solve());
		}
		
		printf("%d\n", res);
	}
}
accuracy: 1
time_ms: 40
memory_kb: 1904
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=(a);i<(b);++i)

struct Point {
	int x, y, s;
	Point(int x_, int y_, int s_) : x(x_), y(y_), s(s_) {}
};

int dx[2][6] = {
		{1, 1, 1, 0, -1, 0}, 
		{0, 1, 0, -1, -1, -1}
	},
	dy[6] = {-1, 0, 1, 1, 0, -1},
	W, H, S, T;

bool vis[110][110], grid[110][110];

vector< Point > search(int sx, int sy) {
	memset(vis, 0, sizeof(vis));
	
	queue< Point > que;
	que.push(Point(sx, sy, 0));
	vis[sy][sx] = 1;
	
	vector< Point > res;
	int mns = int(1e9);
	
	while (!que.empty()) {
		Point p = que.front(); que.pop();
		
		if (mns < p.s) break;
		
		if (grid[p.y][p.x]) {
			mns = p.s;
			res.push_back(p);
			continue;
		}
		
		for_(d,0,6) {
			int nx = p.x + dx[p.y % 2][d], ny = p.y + dy[d];
			if (nx <= 0 || W < nx || ny <= 0 || H < ny) continue;
			if (vis[ny][nx]) continue;
			vis[ny][nx] = 1;
			que.push(Point(nx, ny, p.s + 1));
		}
	}
	
	return res;
}

int main() {	
	while (cin >> W >> H, W) {
		memset(grid, 0, sizeof(grid));
		
		cin >> S;		
		for_(i,0,S) {
			int x, y;
			cin >> x >> y;
			grid[y][x] = 1;
		}
		
		int ans = 0;
		
		cin >> T;
		for_(i,0,T) {
			int x, y;
			cin >> x >> y;
			grid[y][x] = 1;
			
			int cnt = 0;
			for_(yy,1,H+1) for_(xx,1,W+1) {
				vector< Point > vp = search(xx, yy);
				if (vp.size() > 1) continue;				
				if (vp[0].x == x && vp[0].y == y) ++cnt;
			}
			
			grid[y][x] = 0;
			ans = max(ans, cnt);
		}
		
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 90
memory_kb: 1248
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <climits>
#include <map>
#include <cstring>
using namespace std;

const int dx[2][6] = {
    {-1, 0, -1, 1, -1, 0},
    {0, 1, -1, 1, 0, 1}
};
const int dy[2][6] = {
    {-1, -1, 0, 0, 1, 1},
    {-1, -1, 0, 0, 1, 1}
};

int m, n;
pair<int,int> bloc[100][100], tmp[100][100];

void dfs(int idx, int x, int y, int dist) {
    if (dist < bloc[y][x].second) {
        bloc[y][x] = make_pair(idx, dist);
        int k = y%2;
        for (int i=0; i<6; ++i) {
            if (0 <= x+dx[k][i] && x+dx[k][i] < m &&
                0 <= y+dy[k][i] && y+dy[k][i] < n) {
                dfs(idx, x+dx[k][i], y+dy[k][i], dist+1);
            }
        }
    } else if (idx != bloc[y][x].first && dist == bloc[y][x].second) {
        bloc[y][x] = make_pair(-1, dist);
    }
}

int main() {
    while (cin >> m >> n, (m || n)) {
        for (int i=0; i<100; ++i) for (int j=0; j<100; ++j) {
            bloc[i][j] = make_pair(INT_MAX, INT_MAX);
        }
        int s;
        cin >> s;
        int x, y;
        for (int i=0; i<s; ++i) {
            cin >> x >> y;
            dfs(i, x-1, y-1, 0);
        }
        int t;
        cin >> t;
        int p, q, res = 0;
        for (int i=0; i<t; ++i) {
            cin >> p >> q;
            memcpy(tmp, bloc, sizeof bloc);
            dfs(s, p-1, q-1, 0);
            int cnt = 0;
            for (int i=0; i<n; ++i) {
                for (int j=0; j<m; ++j) {
                    if (bloc[i][j].first == s) {
                        ++ cnt;
                    }
                }
            }
            res = max(res, cnt);
            memcpy(bloc, tmp, sizeof tmp);
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 1468
final_rank: 6

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <climits>
#include <map>
#include <cstring>
using namespace std;

const int dx[2][6] = {
    {-1, 0, -1, 1, -1, 0},
    {0, 1, -1, 1, 0, 1}
};
const int dy[2][6] = {
    {-1, -1, 0, 0, 1, 1},
    {-1, -1, 0, 0, 1, 1}
};

int m, n;
pair<int,int> bloc[100][100], tmp[100][100];

void dfs(int idx, int x, int y, int dist) {
    if (dist < bloc[y][x].second) {
        bloc[y][x] = make_pair(idx, dist);
        for (int i=0; i<6; ++i) {
            if (0 <= x+dx[y%2][i] && x+dx[y%2][i] < m &&
                0 <= y+dy[y%2][i] && y+dy[y%2][i] < n) {
                dfs(idx, x+dx[y%2][i], y+dy[y%2][i], dist+1);
            }
        }
    } else if (idx != bloc[y][x].first && dist == bloc[y][x].second) {
        bloc[y][x] = make_pair(-1, dist);
    }
}

int main() {
    while (cin >> m >> n, (m || n)) {
        for (int i=0; i<100; ++i) for (int j=0; j<100; ++j) {
            bloc[i][j] = make_pair(INT_MAX, INT_MAX);
        }
        int s;
        cin >> s;
        int x, y;
        for (int i=0; i<s; ++i) {
            cin >> x >> y;
            dfs(i, x-1, y-1, 0);
        }
        int t;
        cin >> t;
        int p, q, res = 0;
        for (int i=0; i<t; ++i) {
            cin >> p >> q;
            memcpy(tmp, bloc, sizeof bloc);
            dfs(s, p-1, q-1, 0);
            int cnt = 0;
            for (int i=0; i<n; ++i) {
                for (int j=0; j<m; ++j) {
                    if (bloc[i][j].first == s) {
                        ++ cnt;
                    }
                }
            }
            res = max(res, cnt);
            memcpy(bloc, tmp, sizeof tmp);
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 1464
final_rank: 5

code_snippet: #include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cassert>
#include<vector>
#include<deque>
using namespace std;
typedef pair<int,int> P;
int n,m,cnt;
int mincost[110][110];
bool visited[110][110];
int dx[2][6] = {{-1,+0,1,0,-1,-1},{+0,+1,1,1,0,-1}};
int dy[2][6] = {{-1,-1,0,1,+1,+0},{-1,-1,0,1,1,+0}};
bool f;
 
void dfs(int x,int y,int cost)
{
  //if(!f)
  //cout << "xy = "  << x << "," << y << " cost = " << cost << endl;
  for(int i=0;i<6;i++)
    {
      int nx = x + dx[y%2][i];
      int ny = y + dy[y%2][i];
      if(!(0 <= nx && nx < m && 0 <= ny && ny < n))
    continue;
      //if(!f)cout << "mincost["<<ny<<"]["<<nx<<"] = " << mincost[ny][nx] << " = cost + 1  = " << cost + 1  << endl;
      if(mincost[ny][nx] > cost+1)
    {
      if(!visited[ny][nx])
        cnt++;
      visited[ny][nx] = true;
      mincost[ny][nx] = cost + 1;
      dfs(nx,ny,cost+1);
    }
    }
}
 
int main()
{
  while(true)
    {
      cin >> m;
      if(!m) break;
      cin >> n;
      for(int i=0;i<n;i++) 
    for(int j=0;j<m;j++)
      mincost[i][j] = (1<<29);  
      f = true;
      int s,t,mex = 0;
      scanf("%d",&s);
      for(int i=0;i<s;i++)
    {
      int x,y;
      scanf("%d %d",&x,&y);
      x--,y--;
      mincost[y][x] = 0;
      dfs(x,y,0);
    }
      f = false;
      scanf("%d",&t);
      for(int i=0;i<t;i++)
    {   
      int pre_mincost[n][m];
      for(int j=0;j<n;j++)
        for(int k=0;k<m;k++)
          pre_mincost[j][k] = mincost[j][k],visited[j][k] = false;
      int p,q;
      scanf("%d %d",&p,&q);
 
      cnt = 1,p--,q--;
      mincost[q][p] = 0,visited[q][p] = true;
       
      dfs(p,q,0);
       
      mex = max(mex,cnt);
      for(int j=0;j<n;j++)
        for(int k=0;k<m;k++)
          mincost[j][k] = pre_mincost[j][k];
    }
      cout << mex << endl;
    }
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 1384
final_rank: 2

code_snippet: //50
#include<iostream>
#include<algorithm>

using namespace std;

int main(){
  for(int m,n;cin>>m>>n,m;){
    int s;
    cin>>s;
    int g[100][100];
    fill(g[0],g[100],1<<29);
    int sh[100][100]={};
    for(int i=1;i<=s;i++){
      int x,y;
      cin>>x>>y;
      x--;
      y--;
      sh[y][x]=i;
      g[y][x]=0;
    }
    int a=0;
    int t;
    cin>>t;
    while(t--){
      int x,y;
      cin>>x>>y;
      x--;
      y--;
      int gg[100][100];
      copy(g[0],g[n],gg[0]);
      int ss[100][100];
      copy(sh[0],sh[n],ss[0]);
      ss[y][x]=-1;
      gg[y][x]=0;
      for(int i=0;i<m*n;i++){
	for(int j=0;j<n;j++){
	  for(int k=0;k<m;k++){
	    for(int l=0;l<6;l++){
	      int dy[]={-1,0,1,1,0,-1};
	      int dx[][6]={{0,1,0,-1,-1,-1},{1,1,1,0,-1,0}};
	      int ny=j+dy[l];
	      int nx=k+dx[j%2][l];
	      if(0<=min(nx,ny)&&ny<n&&nx<m){
		int c=gg[ny][nx]+1;
		if(c<gg[j][k]){
		  gg[j][k]=c;
		  ss[j][k]=ss[ny][nx];
		}else if(c==gg[j][k]){
		  if(ss[j][k]!=ss[ny][nx]){
		    ss[j][k]=0;
		  }
		}
	      }
	    }
	  }
	}
      }
      int c=0;
      for(int i=0;i<n;i++){
	for(int j=0;j<m;j++){
	  c+=ss[i][j]==-1;
	}
      }
      a=max(c,a);
    }
    cout<<a<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 1304
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

const int MAX_N = 101;
const int INF = 1e+9;
typedef pair<int,int> P;

int w, h;
// st[y][x] := (x,y) が店舗かどうか
int st[MAX_N][MAX_N];

// 移動6方向のベクトル(偶数列と奇数列で遷移の仕方が異なる)
int dx[2][6] = {  
	{ -1, 0, -1, 1, -1, 0 },
	{  0, 1, -1, 1,  0, 1 }
};
int dy[6] = { -1, -1, 0, 0, 1, 1 };

// BFSのときに利用
int d[MAX_N][MAX_N];
// m[y][x] := (x,y) から最短の店舗までの距離
int m[MAX_N][MAX_N];
// 解
int ans;

void init(){
	for(int y=0 ; y < MAX_N ; y++ ){
		for(int x=0 ; x < MAX_N ; x++ ){
			m[y][x] = st[y][x] = 0;
		}
	}
}

void clear_d(){
	for(int y=0 ; y < MAX_N ; y++ ){
		for(int x=0 ; x < MAX_N ; x++ ){
			d[y][x] = INF;
		}
	}
}

// (sx,sy) から最短の店舗までの距離を求める
void bfs(int sx, int sy){
	queue<P> q;
	clear_d();
	q.push( P(sx,sy) );
	d[sy][sx] = 0;
	
	while( !q.empty() ){
		int px = q.front().first; 
		int py = q.front().second;
		q.pop();
		
		if( st[py][px] == 1 ){
			m[sy][sx] = d[py][px];
			break;
		}
		for(int i=0 ; i < 6 ; i++ ){
			int mx = px + dx[py%2][i];
			int my = py + dy[i];
			if( mx < 0 || my < 0 || mx >= w || my >= h ) continue;
			
			if( d[my][mx] == INF ){
				q.push( P(mx,my) );
				d[my][mx] = d[py][px] + 1;
			}
		}
	}
}

// (sx,sy) からカバーできるブロック数
int solve(int sx, int sy){
	queue<P> q;
	clear_d();
	q.push( P(sx,sy) );
	d[sy][sx] = 0;
	int cnt = 0;
	
	while( !q.empty() ){
		int px = q.front().first; 
		int py = q.front().second;
		q.pop();
		if( d[py][px] < m[py][px] ){
			cnt++;
		}else{
			continue;
		}
		
		for(int i=0 ; i < 6 ; i++ ){
			int mx = px + dx[py%2][i];
			int my = py + dy[i];
			if( mx < 0 || my < 0 || mx >= w || my >= h ) continue;
			
			if( d[my][mx] == INF ){
				q.push( P(mx,my) );
				d[my][mx] = d[py][px] + 1;
			}
		}
	}
	return cnt;
}

int main(){
	while( cin >> w >> h , w || h ){
		init();
		
		int s, t;
		cin >> s;
		for(int i=0 ; i < s ; i++ ){
			int x, y;
			cin >> x >> y;
			x--; y--;
			st[y][x] = 1;
		}
		
		for(int y=0 ; y < h ; y++ ){
			for(int x=0 ; x < w ; x++ ){
				bfs( x , y );
			}
		}
		
		ans = 0;
		cin >> t;
		for(int i=0 ; i < t ; i++ ){
			int x, y;
			cin >> x >> y;
			x--; y--;
			int cnt = solve( x, y );
			ans = max( ans , cnt );
		}
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 160
memory_kb: 1028
final_rank: 7

code_snippet: #include <iostream>
#include <queue>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
typedef pair<pair<int,int>,int> NODE;
#define X first.second
#define Y first.first
#define depth second

/*ï*/
int ox[] = {-1, 1, 0, 0, 1,1};
int oy[] = { 0, 0,-1, 1,-1,1};

/*ô*/
int ex[] = {-1, 1, 0, 0,-1,-1};
int ey[] = { 0, 0,-1, 1,-1, 1};

int main(){
	int point[100][100];
	int h,w,a,b,t,x,y,s;
	while(cin >> w  && w){
		int ret = 0;
		cin >> h;
		rep(i,100)rep(j,100)point[i][j] = 0;
		cin >> t;
		rep(i,t){
			cin >> a >> b;
			a--;b--;
			point[b][a] = i+1;
		}
		cin >> s;
		rep(P,s){
			cin >> a >> b;
			a--;b--;
			point[b][a] = 50;
			
		//rep(i,h){rep(j,w)cout << point[i][j];cout << endl;}
		int pt[100] = {0};
		rep(i,h)rep(j,w){
			x = j,y = i;
			queue<NODE> Q;
			pair<int,int> dp[100];
			bool done[100][100]={0};
			Q.push( make_pair(make_pair(y,x),0	) );
			while( Q.size() ){
				NODE q = Q.front(); Q.pop();
				if(point[q.Y][q.X]){
					dp[q.depth].first++;
					dp[q.depth].second = point[q.Y][q.X];
			  }
				if( q.Y % 2 == 1){
					rep(L,6){
						if( q.X+ox[L] >=0 && q.X+ox[L] < w && q.Y+oy[L] < h && q.Y+oy[L]>=0 ){
								if( !done[q.Y+oy[L]][q.X+ox[L]] )Q.push( make_pair(make_pair(q.Y+oy[L],q.X+ox[L]),q.depth+1) );
							  	done[q.Y+oy[L]][q.X+ox[L]] = true;
						}
					}
				}else{
					rep(L,6){
						if( q.X+ex[L] >=0 && q.X+ex[L] < w && q.Y+ey[L] < h && q.Y+ey[L]>=0 ){
									if( !done[q.Y+ey[L]][q.X+ex[L]] )Q.push( make_pair(make_pair(q.Y+ey[L],q.X+ex[L]),q.depth+1) );
							  	done[q.Y+ey[L]][q.X+ex[L]] = true;
						}
					}
				}
			}
			rep(I,100){
				if(dp[I].first){
					if(dp[I].first==1)
						pt[dp[I].second-1]++;
					break;
				}
			}
		}
			ret = max(pt[49],ret);
			point[b][a] = 0;
		}
		cout << ret << endl;
	}
	
}
accuracy: 1
time_ms: 260
memory_kb: 960
final_rank: 9

code_snippet: #include<iostream>
#include<queue>
#include<set>

#define INV (-1)
#define MAX 128
#define MAX_ENEMY 10
#define MAX_STORE 21

using namespace std;

const int even_di[] = {-1,-1,0,0,1,1};
const int even_dj[] = {0,1,-1,1,0,1};
const int odd_di[] = {-1,-1,0,0,1,1};
const int odd_dj[] = {-1,0,-1,1,-1,0};
const int infty = 1 << 26;

class Area{
 public:
  int store;
  int dist[MAX_STORE];
  bool valid;
  Area():store(INV),valid(false){
    for(int i = 0; i < MAX_STORE; ++i){
      dist[i] = infty;
    }
  }
};

class Map{
 public:
  int n,m;
  Area T[MAX][MAX];
  Map(){}
  Map(int n, int m):n(n),m(m){
    for(int i = 1; i < n+1; ++i){
      for(int j = 1; j < m+1; ++j){
	T[i][j].valid = true;
	for(int k = 0; k < MAX_STORE; ++k){
	  T[i][j].dist[k] = infty;
	}
      }
    }
  }
  int occupied(int store){
    int ret = 0;
    for(int i = 1; i < n + 1; ++i){
      for(int j = 1; j < m + 1; ++j){
	int minimum = infty;
	int id = -1;
	int cnt = 0;
	for(int k = 0; k < MAX_STORE; ++k){
	  if( k >= MAX_ENEMY && k != store ) continue;
	  minimum = min( minimum, T[i][j].dist[k] ); 
	}
	for(int k = 0; k < MAX_STORE; ++k){
	  if( k >= MAX_ENEMY && k != store ) continue;
	  if( minimum == T[i][j].dist[k] ){
	    ++cnt;
	    id = k;
	  }
	}
	if( cnt == 1 && id == store ){
	  ++ret;
	}
      }
    }
    return ret;
  }
};

class State
{
public:
  int i,j;
  int cost;
  State():i(0),j(0),cost(infty){}
  State(int i, int j, int cost):i(i),j(j),cost(cost){}
};
  
void store_bfs( int i, int j, int store, Map &M )
{
  queue< State > qpi;
  set<pair<int,int> > vis;
  qpi.push( State(i,j,0) );

  vis.insert(make_pair(i,j));
  while(!qpi.empty()){
    State now = qpi.front();
    qpi.pop();

    M.T[now.i][now.j].dist[store] = now.cost;
    
    for(int i = 0; i < sizeof(even_di)/sizeof(*even_di); ++i){
      int ti = now.i + ( now.i%2==0 ? even_di[i] : odd_di[i] );
      int tj = now.j + ( now.i%2==0 ? even_dj[i] : odd_dj[i] );
      
      if( !M.T[ti][tj].valid ) continue;
      if( vis.find( make_pair( ti, tj ) ) != vis.end() ) continue;
      
      vis.insert( make_pair( ti, tj ) );
      qpi.push( State(ti,tj,now.cost+1) );
    }
  }
}

int main()
{
  while(true){
    int m,n;
    int ans = 0;
    cin >> m;
    if( m == 0 ) break;
    cin >> n;
    if( n == 0 ) break;
    int st;
    Map M(n,m);
    
    cin >> st;
    for(int i = 0; i < st; ++i){
      int y,x;
      cin >> x >> y;
      //++x;++y;
      M.T[y][x].store = i;
      store_bfs( y, x, i, M );
    }
    
    int cands;
    cin >> cands;
    for(int i = 0; i < cands; ++i){
      int y,x;
      cin >> x >> y;
      //++x;++y;
      M.T[y][x].store = MAX_ENEMY + i;
      store_bfs( y, x, MAX_ENEMY+i, M );
    }
    

    /*
    for(int i = 0; i < n+2; ++i){
      for(int j = 0; j < m+2; ++j){
	cout << "(" << j << " , " << i << ") = ";
	for(int k = 0; k < MAX_STORE; ++k){
	  cout << M.T[i][j].dist[k] << ' ';
	}
	cout << endl;
      }
      cout << "--------" << endl;
    }
    */
    

    for(int i = 0; i < cands; ++i){
      ans = max( ans, M.occupied( MAX_ENEMY + i ) );
    }

    cout << ans << endl;
    
  }
  return 0;

}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#define rep(i,n) for(int i=0;i<n;i++)
#define ck(a,b) (0<=a&&a<b)
#define INF 1<<30
using namespace std;
int dx0[]={0,1,0,-1,-1,-1},dx1[]={1,1,1,0,-1,0},dy[]={-1,0,1,1,0,-1};
int md[100][100],td[100][100],s,t,sx[10],sy[10],tx[10],ty[10],m,n,tc,mc;
void rec(int x,int y,int a){
	td[x][y]=a;
	rep(d,6){
		int nx=x+(y%2?dx1[d]:dx0[d]),ny=y+dy[d];
		if(ck(nx,m)&&ck(ny,n)&&td[nx][ny]>a+1)rec(nx,ny,a+1);
	}
}
int main(){
	while(cin>>m>>n>>s,m){
		rep(i,m)rep(j,n)md[i][j]=INF;
		rep(i,s)cin>>sx[i]>>sy[i],sx[i]--,sy[i]--;
		cin>>t; rep(i,t)cin>>tx[i]>>ty[i],tx[i]--,ty[i]--;
		rep(i,s){
			rep(k,m)rep(l,n)td[k][l]=INF;
			rec(sx[i],sy[i],0);
			rep(k,m)rep(l,n)if(md[k][l]>td[k][l])md[k][l]=td[k][l];
		}
		mc=0; rep(i,t){
			tc=0;
			rep(k,m)rep(l,n)td[k][l]=INF;
			rec(tx[i],ty[i],0);
			rep(k,m)rep(l,n)if(md[k][l]>td[k][l])tc++;
			if(mc<tc)mc=tc;
		}
		cout<<mc<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 1020
final_rank: 8