棋盘占领
Accepts: 937
Submissions: 2201
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
用模拟的方法,维持一个队列和一个矩阵,将初始点全部输入队列中,矩阵对应被占领城池标记为1,未占领标记为0。
以后每一趟检查每个点的四个斜角处,如果有点,将对应的 2 X 2 区域填满,并将新占领的点压入队列。检查完毕后,将检查的点推出队列。
此题还存在更好的算法。
#include <iostream>
#include <queue>
#include <map>
using namespace std;
typedef pair<int ,int> point;
int main()
{
int T;
cin >> T;
for(int i = 1; i <= T; i++) {
int n, m, N, count = 0;
queue<pair<int, int> > qp;
cin >> n >> m >> N;
bool a[n][m];
for(int j = 0; j < n ; j++) {
for(int k = 0; k < m; k++) {
a[j][k] = false;
}
}
for(int j = 0; j < N; j++) {
point p;
cin >> p.first >> p.second;
p.first--;
p.second--;
qp.push(p);
if(!a[p.first][p.second]) count++;
a[p.first][p.second] = true;
}
while(!qp.empty()) {
point p = qp.front();
int x0 = p.first, y0 = p.second;
int x = x0 - 1, y = y0 - 1;
if(x >= 0 && x <= n - 1 && y >= 0 && y <= m - 1) {
if(a[x0 - 1][y0 - 1]) {
if(!a[x0-1][y0]) {
point p1(x0-1,y0);
qp.push(p1);
count++;
a[x0-1][y0] = true;
}
if(!a[x0][y0-1]) {
point p1(x0,y0-1);
qp.push(p1);
count++;
a[x0][y0-1] = true;
}
}
}
x = x0 + 1, y = y0 - 1;
if(x >= 0 && x <= n - 1 && y >= 0 && y <= m - 1) {
if(a[x0 + 1][y0 - 1]) {
if(!a[x0+1][y0]) {
point p1(x0+1,y0);
qp.push(p1);
count++;
a[x0+1][y0] = true;
}
if(!a[x0][y0-1]) {
point p1(x0,y0-1);
qp.push(p1);
count++;
a[x0][y0-1] = true;
}
}
}
x = x0 - 1, y = y0 + 1;
if(x >= 0 && x <= n - 1 && y >= 0 && y <= m - 1) {
if(a[x0 - 1][y0 + 1]) {
if(!a[x0-1][y0]) {
point p1(x0-1,y0);
qp.push(p1);
count++;
a[x0-1][y0] = true;
}
if(!a[x0][y0+1]) {
point p1(x0,y0+1);
qp.push(p1);
count++;
a[x0][y0+1] = true;
}
}
}
x = x0 + 1, y = y0 + 1;
if(x >= 0 && x <= n - 1 && y >= 0 && y <= m - 1) {
if(a[x0 + 1][y0 + 1]) {
if(!a[x0+1][y0]) {
point p1(x0+1,y0);
qp.push(p1);
count++;
a[x0+1][y0] = true;
}
if(!a[x0][y0+1]) {
point p1(x0,y0+1);
qp.push(p1);
count++;
a[x0][y0+1] = true;
}
}
}
qp.pop();
}
cout << "Case #"<< i <<":" << endl;
cout << count << endl;
}
return 0;
}