微软大楼设计方案(困难) 解题报告

来源:互联网 发布:网名生成器软件下载 编辑:程序博客网 时间:2024/05/19 00:43

原题链接:

微软大楼设计方案(困难)

解题思路:

运用动态规划、二分查找。

  1. 计算每一个hij,i是第i栋楼,j是j层。hij是包括第i栋楼第j层在内以左以下的楼高为j的栋数。
  2. 运用二分查找、条件不等式求协同值。
  3. 协同值可能会让int溢出,因此需要long long。

代码:

#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <cstdlib>#include <cassert>#include <cmath>#include <vector>#include <algorithm>using namespace std;struct pos {int x, y;pos(int x = 0, int y = 0) : x(x), y(y) {}bool operator<(const pos p){if (x < p.x) {return true;}else if (x == p.x && y < p.y) {return true;}else {return false;}}};int query(const vector<int>& h1, const vector<int>& h2);int binarySearch(const vector<pos>& posArray, const int value);int main(){int n = 0, k = 0;assert(2 == scanf("%d %d", &n, &k));vector<int> hArray(n + 1);vector<vector<int>> h(n + 1);for (int i = 1; i <= n; i++) {assert(scanf("%d", &hArray[i]) == 1);if (i != 1) {h[i] = h[i - 1];}else {h[i].resize(21);}h[i][hArray[i]]++;}int m = 0;assert(1 == scanf("%d", &m));vector<pos> posArray(m);for (int i = 0; i < m; i++) {assert(2 == scanf("%d %d", &posArray[i].x, &posArray[i].y));}sort(posArray.begin(), posArray.end());long long recouncil = 0;for (int i = 0; i < m; i++) {int right = 0;int rIndex = 0;right = posArray[i].x + k - 38;if (right >= posArray[m - 1].x) {recouncil += m - 1 - i;continue;}else if (right < posArray[i].x) {rIndex = i + 1;}else {rIndex = binarySearch(posArray, right);recouncil += rIndex - 1 - i;}for (int j = rIndex; j < m; j++) {pos start(posArray[i].x, posArray[i].y), end(posArray[j].x, posArray[j].y);if (end < start) {swap(start, end);}if (end.x - start.x > k) {break;}int minY = query(h[posArray[i].x], h[posArray[j].x]);minY = min(minY, start.y);minY = min(minY, end.y);int cost = end.x - start.x + start.y + end.y - 2 * minY;if (cost <= k) {recouncil++;}else if(cost > k + 20) {break;}}}printf("%lld\n", recouncil);return 0;}int query(const vector<int>& h1, const vector<int>& h2){int min = 0;for (int i = 1; i <= 20; i++) {if (h2[i] - h1[i]) {min = i;break;}}return min;}int binarySearch(const vector<pos>& posArray, const int value){int left = 0, right = posArray.size() - 1, mid = 0;while (left < right) {mid = left + ((right - left) >> 1);if (posArray[mid].x <= value) {left = mid + 1;}else {right = mid;}}return left;}

阅读全文
0 0