题目描述
Farmer John has devised a brilliant method to paint the long fence next to his barn (think of the fence as a one-dimensional number line). He simply attaches a paint brush to his favorite cow Bessie, and then retires to drink a cold glass of water as Bessie walks back and forth across the fence, applying paint to any segment of the fence that she walks past.
Bessie starts at position 0 on the fence and follows a sequence of N moves (1 <= N <= 100,000). Example moves might be "10 L", meaning Bessie moves 10 units to the left, or "15 R", meaning Bessie moves 15 units to the right. Given a list of all of Bessie's moves, FJ would like to know what area of the fence gets painted with at least K coats of paint. Bessie will move at most 1,000,000,000 units away from the origin during her walk.
Farmer John 想出了一个给牛棚旁的长围墙涂色的好方法。(为了简单起见,我们把围墙看做一维的数轴,每一个单位长度代表一块栅栏)他只是简单的把刷子蘸满颜料,系在他最喜欢的奶牛Bessie上,然后让Bessie来回地经过围墙,自己则在一旁喝一杯冰镇的凉水。(……-_-|||) Bessie 经过的所有围墙都会被涂上一层颜料。Bessie从围墙上的位置0出发,并将会进行N次移动(1 <= N <= 100,000)。比如说,“10 L”的意思就是Bessie向左移动了10个单位。再比如说“15 R”的意思就是Bessie向右移动了15个单位。给出一系列Bessie移动的清单。FJ 想知道有多少块栅栏涂上了至少K层涂料。注意:Bessie最多会移动到离原点1,000,000,000单位远的地方。
输入输出格式
输入格式:* 第1行: 两个整数: N K
* 第2...N+1 行: 每一行都描述了Bessie的一次移动。 (比如说 “15 L")
* 一个整数:被至少涂上K层涂料的栅栏数
(注意:输出的最后一定要输出换行符!否则会WA)
题解:
扫描线,记录一条线段的左端点l,右端点r,当你"扫描"到l时,表示你进入了这条线段,当你扫描到r时,表示你离开了这条线段,所以这条线段的覆盖区间为[l,r)。
那么在这题中也是一样,我们记录每个区间的左端点和右端点,并进行一次排序,然后一遍扫过去,当扫描到所在的线段>=k时,统计答案。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int Maxn=100005;
int n,k,ans;
struct node{
int x,v;
}a[Maxn*2];
bool cmp(node x,node y){
return x.x<y.x;
}
int now;
int main(){
int u;
char v;
scanf("%d%d\n",&n,&k);
for(int i=1;i<=n*2;i+=2){
scanf("%d %c\n",&u,&v);
if(v=='R'){
a[i].v=1;a[i].x=now;
now+=u;
a[i+1].v=-1;a[i+1].x=now;
}
else{
a[i].v=-1;a[i].x=now;
now-=u;
a[i+1].v=1;a[i+1].x=now;
}
}
n*=2;
sort(a+1,a+1+n,cmp);
now=0;
for(int i=1;i<=n;i++){
now+=a[i].v;
if(now>=k){
ans+=a[i+1].x-a[i].x;
}
}
printf("%d\n",ans);
return 0;
}