小B特别喜欢玩一款模拟城市建设的游戏,她觉得看着城市从自己的手中诞生超有成就感。游戏地图是一个由n*m个单元构成的矩形区域,每个单元的属性为其平均高度。小B的任务是在其中建设若干城市,每个城市为地图中a*b个单元大小的矩形区域。
为开展城市建设,需要先平整土地。小B的做法是从选定的区域中选择最低的单元,将其他单元平整为与该单元相同的高度。把高度为h2的单元平整到高度h1时,需要挖掘h2-h1单位的土石。为减少土石挖掘量,需要选择最佳的建设地点,使得挖掘的土石量最小。
小B按照如下方式开展城市建设工作,从所有可能的最佳建设地点中选择位于最上方的那个,若存在多个,则选择最左侧的位置,并在该位置开始城市建设工作。重复该过程以建成其他城市。若有单元已经被占用,则不能在其上开展建设工作。你能帮助小B找到合适的城市建设位置吗?
输入
测试数据有多组,每组测试数据的第一行为四个整数n, m, a, b(1=< a =< n <=1000, 1=< b =< m <=1000),表示地图的大小和城市的大小。随后的n行中每行有m个非负整数,表示区域中各个单元的平均高度,每个整数大小不超过10^9。
输出
对每组测试数据,先在第一行中输出一个数k,表示可以建设的城市数,在紧随其后的k行中,每行输出3个空格分隔的整数,分别表示该城市所在位置的左上角行号、列号以及需要挖掘的土石量。
样例输入
2 2 1 2
1 2
3 5
4 4 2 2
1 5 3 4
2 7 6 1
1 1 2 2
2 2 1 2
样例输出
2
1 1 1
2 1 2
3
3 1 2
3 3 3
为开展城市建设,需要先平整土地。小B的做法是从选定的区域中选择最低的单元,将其他单元平整为与该单元相同的高度。把高度为h2的单元平整到高度h1时,需要挖掘h2-h1单位的土石。为减少土石挖掘量,需要选择最佳的建设地点,使得挖掘的土石量最小。
小B按照如下方式开展城市建设工作,从所有可能的最佳建设地点中选择位于最上方的那个,若存在多个,则选择最左侧的位置,并在该位置开始城市建设工作。重复该过程以建成其他城市。若有单元已经被占用,则不能在其上开展建设工作。你能帮助小B找到合适的城市建设位置吗?
输入
测试数据有多组,每组测试数据的第一行为四个整数n, m, a, b(1=< a =< n <=1000, 1=< b =< m <=1000),表示地图的大小和城市的大小。随后的n行中每行有m个非负整数,表示区域中各个单元的平均高度,每个整数大小不超过10^9。
输出
对每组测试数据,先在第一行中输出一个数k,表示可以建设的城市数,在紧随其后的k行中,每行输出3个空格分隔的整数,分别表示该城市所在位置的左上角行号、列号以及需要挖掘的土石量。
样例输入
2 2 1 2
1 2
3 5
4 4 2 2
1 5 3 4
2 7 6 1
1 1 2 2
2 2 1 2
样例输出
2
1 1 1
2 1 2
3
3 1 2
3 3 3
1 2 9
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, m, a, b;
while (cin >> n >> m >> a >> b) {
int* map = new int[n*m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
cin >> map[i*m + j];
}
int* cost = new int[n*m];
memset(cost, -1, n*m*sizeof(int));
bool* visited = new bool[n*m];
memset(visited, false, n*m*sizeof(bool));
// calculate all cost
int min = 0, sum = 0, count = 0;
for (int i = 0; i < n - a + 1; i++) {
for (int j = 0; j < m - b + 1; j++) {
min = map[i*n + j];
sum = 0;
for (int a1 = 0; a1 < a; a1++) {
for (int b1 = 0; b1 < b; b1++) {
sum += map[(i + a1)*n + j + b1];
if (map[(i + a1)*n + j + b1] < min)
min = map[(i + a1)*n + j + b1];
}
}
sum -= a*b * min;
cost[i*n + j] = sum;
count++;
}
}
// print
int min_cost = 1e10, min_i = -1, min_j = -1;
vector<int> aa, bb, cc;
while (count-- > 0) {
min_cost = 1e10, min_i = -1, min_j = -1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
bool v = false;
for (int a1 = 0; a1 < a; a1++) {
for (int b1 = 0; b1 < b; b1++) {
if (visited[(i + a1)*n + j + b1] == true)
v = true;
}
}
if (v == false && cost[i*n + j] >= 0 && cost[i*n + j] < min_cost) {
min_cost = cost[i*n + j];
min_i = i;
min_j = j;
}
}
}
if (min_i != -1) {
for (int a1 = 0; a1 < a; a1++) {
for (int b1 = 0; b1 < b; b1++) {
if (visited[(min_i + a1)*n + min_j + b1] == false)
visited[(min_i + a1)*n + min_j + b1] = true;
}
}
aa.push_back(min_i + 1);
bb.push_back(min_j + 1);
cc.push_back(min_cost);
}
}
cout << aa.size() << endl;
for (int i = 0; i < aa.size(); i++) {
cout << aa[i] << " " << bb[i] << " " << cc[i] << endl;
}
}
return 0;
}