51nod 1562 玻璃切割 (STL map+一点点的思考)
1562 玻璃切割
題目來源: CodeForces
基準時間限制:1.5 秒 空間限制:131072 KB 分值: 20 難度:3級算法題
現在有一塊玻璃,是長方形的(w 毫米× h 毫米),現在要對他進行切割。
切割的方向有兩種,橫向和縱向。每一次切割之后就會有若干塊玻璃被分成兩塊更小的玻璃。在切割之后玻璃不會被移動。
現在想知道每次切割之后面積最大的一塊玻璃是多少。
樣例解釋:
對于第四次切割,下面四塊玻璃的面積是一樣大的。都是2。
Input
單組測試數據。
第一行有三個整數 w,h,n (2≤w,h≤200000, 1≤n≤200000),表示玻璃在橫向上長w 毫米,縱向上長h 毫米,接下來有n次的切割。
接下來有n行輸入,每一行描述一次切割。
輸入的格式是H y 或 V x。
H y表示橫向切割,切割線距離下邊緣y毫米(1≤y≤h-1)。
V x表示縱向切割,切割線距離左邊緣x毫米(1≤x≤w-1)。
輸入保證不會有兩次切割是一樣的。
Output
對于每一次切割,輸出所有玻璃中面積最大的是多少。
Input示例
樣例輸入1
4 3 4
H 2
V 2
V 3
V 1
Output示例
樣例輸出1
8
4
4
這題我們只有一個需要思考的點,那就是什么切割了多次之后怎樣的一塊面積最大?
我們可以想到橫向最寬,縱向最高的面積一定是最大的。
然后要注意的一點是,橫向和縱向處理很容易把人弄暈,
可以先考慮線段的情況,問題變成了,一條線段,切割之后最長的子線段為多少?
求出一個維度之后復制粘貼變成2維的即可。
寫起來很繞,需要很強的編碼能力,不過這與問題的解決辦法已經無關了。
代碼:
#include <iostream> #include <algorithm> #include <map> #include <vector> #include <set> #include <math.h> #include <queue> #include <assert.h> #include <stdio.h> #include <stdlib.h> using namespace std; typedef long long ll; #define INF 2147483647//輸入 int w, h, n;//mh:高度方向上每個間隔出現的次數。mh[i] = j表示間隔為i的線段有j個。 //mv:寬度方向上每個間隔出現的次數。mv[i] = j表示間隔為i的線段有j個。 //h1: h1[i] = j表示高度方向上切割點為i的線段的長度為j。 //v1: v1[i] = j表示寬度方向上切割點為i的線段的長度為j。 map <int, int> mh, mv, h1, v1; map <int, int>::iterator it, it1;int main() {scanf("%d%d%d", &w, &h, &n);//初始化,長度為h的線段+1,長度為w的線段+1,以0為起點的線段長為h,以0為起點的線段長為w。 mh[h] = 1;mv[w] = 1;h1[0] = h;v1[0] = w;char k1;int k2;while (n--) {getchar();scanf("%c%d", &k1, &k2);if (k1 == 'H') {//找到切割點前一個點的位置和長度。 it = h1.lower_bound(k2); it--;int con = it->first;int len = it->second;//長度為len的線段-1,如果為0了就從map中刪掉 mh[len]--;if (mh[len] == 0) mh.erase(len);//h1: h1[i] = j表示高度方向上切割點為i的線段的長度為j。h1[con] = k2 - con;h1[k2] = len - h1[con];//mh:高度方向上每個間隔出現的次數。mh[i] = j表示間隔為i的線段有j個。 mh[h1[k2]]++;mh[h1[con]]++;}else if (k1 == 'V') {it = v1.lower_bound(k2); it--;int con = it->first;int len = it->second;mv[len]--;if (mv[len] == 0) mv.erase(len);v1[con] = k2 - con;v1[k2] = len - v1[con];mv[v1[k2]]++;mv[v1[con]]++;}//map最后一個值的key最大 it = mh.end(); it--;it1 = mv.end(); it1--;ll p = it->first;ll q = it1->first;printf("%lld\n", p*q);}getchar(); getchar();return 0; } /* 10 10 5 H 1 H 8 H 6 H 2 H 4 */總結
以上是生活随笔為你收集整理的51nod 1562 玻璃切割 (STL map+一点点的思考)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 51nod 1021 石子归并 (动态规
- 下一篇: 51nod 1649 齐头并进 (dji