(File IO): input:paint.in output:paint.out
时间限制: 1000 ms 空间限制: 128001 KB 具体限制
Goto ProblemSet
题目描述
农夫约翰最近正在将他的栅栏粉刷一下(这里所有的栅栏都是在一条直线上的)。他是这样来粉刷的:他从位置
0
0
0出发,然后执行
N
N
N条指令,例如,指令可以是
“
10
L
”
“10 L”
“10L”,表示约翰从当前的位置向左移动
10
10
10个单位的距离,并且粉刷移动过程中遇到的栅栏,又或者是
“
15
R
”
“15 R”
“15R”,表示约翰从当前的位置向右移动
15
15
15个单位的距离,并且粉刷移动过程中遇到的栅栏。
给定所有约翰需要移动的指令,请计算所有栅栏中至少被粉刷两次的栅栏的总长度。约翰最多远离初始位置
1000000000
1000000000
1000000000个单位的距离。
输入
第一行一个正整数
N
N
N。
接下来第
2
2
2行到第
N
+
1
N+1
N+1行,每行表示每条指令。
输出
只有一行一个整数,表示所有栅栏中至少被粉刷两次的栅栏的总长度。
样例输入
6
2 R
6 L
1 R
8 L
1 R
2 R
样例输出
6
数据范围限制
1<=N<=100000。
提示
说明:样例中,有
6
6
6个单位的长度至少被粉刷两次。分别是
[
−
11
,
−
8
]
,
[
−
4
,
−
3
]
,
[
0
,
2
]
[-11,-8],[-4,-3],[0,2]
[−11,−8],[−4,−3],[0,2]。
解题思路
把每一次的操作变成一个区间,存区间的右端和左端。。
按照从小到大的顺序快排。。然后纯模拟,五种情况分类讨论。。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
int x,ans,h,t,n;
string s;
char c;
struct cc{
int x,y;
}a[150000];
bool cmp(const cc&l,const cc&r){
return (l.x<r.x)||(l.x==r.x&&l.y<r.y);
}
int main(){
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
int y;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
cin>>c;
if(c=='R')
x=y+x;
else
x=y-x;
a[i].x=min(x,y);
a[i].y=max(x,y);
y=x;
}
sort(a+1,a+n+1,cmp);
h=a[1].x;
t=a[1].y;
for(int i=2;i<=n;i++)
{
if(a[i].y<h)continue;
if(a[i].y<=t){
ans=ans+a[i].y-max(a[i].x,h);
h=a[i].y;
}
else if(a[i].x>t){
h=a[i].x;
t=a[i].y;
}
else if(a[i].x<h){
ans=ans+t-h;
h=t;
t=a[i].y;
}
else{
ans=ans+t-a[i].x;
h=t;
t=a[i].y;
}
}
cout<<ans;
}