农夫约翰发明了一种绝妙的方法来粉刷牛棚旁边的长栅栏(把栅栏想象成一维的数轴)。
他只需要在他最喜欢的奶牛贝茜身上挂一个刷子,然后在一旁悠闲的喝凉水就行了。
贝茜沿着栅栏来回走动时,会将她走过的栅栏部分涂上油漆。
贝茜从栅栏上的位置 \(0\) 处开始,共进行 \(N\) 次移动。
移动可能形如 10 L
,表示向左移动 \(10\) 单位距离,也可能形如 15 R
,表示向右移动 \(15\) 单位距离。
给定贝茜的 \(N\) 次移动列表,约翰想知道至少被涂抹了 \(2\) 层油漆的区域的总长度。
整个行进过程中,贝茜距离出发地的距离不会超过 \(10^9\)。
第一行包含一个整数 \(N\)。
接下来 \(N\) 行,每一行包含一个行动指令,诸如 10 L
或 15 R
。
输出至少被涂抹了 \(2\) 层油漆的区域的总长度。
\(1≤N≤10^5\)
整个行进过程中,贝茜距离出发地的距离不会超过 \(10^9\)。
每次指令移动距离的取值范围是 \([1,2×10^9]\)。
6 2 R 6 L 1 R 8 L 1 R 2 R
6
共有 \(6\) 单位长度的区域至少被涂抹 \(2\) 层油漆。
这些区域为 \((−11,−8),(−4,−3),(0,2)\)。
差分,离散化,map
显然是一道差分+离散化模板题,这里用map
实现,离散化之后的区间都是权值连续的区间,即从开始到某个点的权值是相同的,从该点后面的点开始再到某个点又是另外一个权值是相同的 \(\dots\),需要注意这里求的是长度而不是点数
// Problem: 粉刷栅栏 // Contest: AcWing // URL: https://www.acwing.com/problem/content/1989/ // Memory Limit: 64 MB // Time Limit: 1000 ms // %%%Skyqwq #include <bits/stdc++.h> #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } int main() { int n; map<int,int> mp; int pos=0; for(scanf("%d",&n);n;n--) { int dis; char op; scanf("%d %c",&dis,&op); if(op=='L') { mp[pos]--; mp[pos-dis]++; pos-=dis; } else { mp[pos]++; mp[pos+dis]--; pos+=dis; } } int res=0,lst,sum=0; for(auto [k,v]:mp) { if(sum>=2)res+=k-lst; lst=k; sum+=v; } printf("%d",res); return 0; }