您的位置:首页 > 编程语言

牛客网2017校招真题编程练习--4.分田地

2018-02-27 15:24 225 查看
                                  牛客网2017校招真题编程练习--4.分田地


#include <iostream>
#include <string>
using namespace std;

int n, m;
const int MAX_LEN = 80;
int lands[MAX_LEN][MAX_LEN];
int sums[MAX_LEN][MAX_LEN];

// calculate the area between upper-left point (star_x, start_y) and lower-right point (end_x, end_y)
int get_area(int start_x, int start_y, int end_x, int end_y)
{
return sums[end_x][end_y] - sums[end_x][start_y]
- sums[start_x][end_y] + sums[start_x][start_y]; //计算lands中左上点(star_x, start_y)和右下点(end_x, end_y)所围田地的价值和
}

bool is_accord_with(int area_value)
{
// traverse three cutting line in the vertical direction
for (int i = 1; i <= m - 3; ++i)
{
for (int j = i + 1; j <= m - 2; ++j)
{
for (int k = j + 1; k <= m - 1; ++k)
{
int areas[4], start_line = 0, content_count = 0;
for (int t = 1; t <= n; ++t)
{
areas[0] = get_area(start_line, 0, t, i);
areas[1] = get_area(start_line, i, t, j);
areas[2] = get_area(start_line, j, t, k);
areas[3] = get_area(start_line, k, t, m);
// meet the condition
if (areas[0] >= area_value && areas[1] >= area_value &&
areas[2] >= area_value && areas[3] >= area_value) //当前横一刀满足条件
{
start_line = t;
++content_count;
}
}
if (content_count >= 4) //表明当前x是16块田地中最小的,返回true
{
return true;
}
}
}
}
return false;
}

int main() {
cin >> n >> m;
string s;
for (int i = 1; i <= n; ++i) {
cin >> s;
for (int j = 1; j <= m; ++j) {
lands[i][j] = s[j - 1] - '0'; //字符-字符'0'的ASCII码得到数值
sums[i][j] = sums[i][j - 1] + sums[i - 1][j] - sums[i - 1][j - 1] + lands[i][j]; //sum[i][j]表示坐标(i,j)左上方价值总和
}
}
int ans = 0;
int left = 0, right = sums
[m]; // sum
[m]表示所有价值总和
while (left <= right) //二分答案,判断可行性时暴力枚举三列的情况,然后横着贪心地扫一遍,每当四个都满足时就砍一刀,满足四次
//即可,复杂度O(N^4logN)
{
int mid = left + ((right - left) >> 1);
if (is_accord_with(mid)) // 表明mid是16块田地最小的
{
ans = mid;
left = mid + 1;
}
else {
right = mid - 1;
}
}
cout << ans << endl;
system("pause");
return 0;
}

知识点:
1. 二分法
   参考博客1:浅谈--二分查找
   参考博客2:二分查找各种情况大总结
   参考博客3:二分查找
2. //字符-字符'0'的ASCII码得到数值


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: