题目描述
农夫约翰最近正在将他的栅栏粉刷一下(这里所有的栅栏都是在一条直线上的)。他是这样来粉刷的:他从位置0出发,然后执行N条指令,例如,指令可以是“10 L”,表示约翰从当前的位置向左移动10个单位的距离,并且粉刷移动过程中遇到的栅栏,又或者是“15 R”,表示约翰从当前的位置向右移动15个单位的距离,并且粉刷移动过程中遇到的栅栏。
现在给定所有约翰需要移动的指令,请计算所有栅栏中至少被粉刷两次的栅栏的总长度。约翰最多远离初始位置1000000000个单位的距离。
输入
第一行一个正整数N。
接下来第2行到第N+1行,每行表示每条指令。
输出
只有一行一个整数,表示所有栅栏中至少被粉刷两次的栅栏的总长度。
样例输入
6
2 R
6 L
1 R
8 L
1 R
2 R
样例输出
6
hint
数据范围:1<=N<=100000。
分析
这题本想用数组直接做,但被数据吓退了…
这题是用区间[x,y]模拟,ans加上区间差就行。像一种类似于队列的操作。。
上代码!
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,ans;
char s;
struct node
{
int q,h;
}a[100010];
int cmp(node x,node y)
{
return (x.q<y.q)||(x.q==y.q&&x.h<y.h);
}
int main()
{
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
cin>>n;
int now;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
cin>>s;
if(s=='L')
{
x=now-x;
}
else x=now+x;
a[i].q=min(x,now);
a[i].h=max(x,now);
now=x;
}
sort(a+1,a+n+1,cmp);
int x=a[1].q;
int y=a[1].h;
for(int i=2;i<=n;i++)
{
if(a[i].h<x) continue;
if(a[i].h<=y)
{
ans+=a[i].h-max(a[i].q,x);
x=a[i].h;
}
else if(a[i].q>y)
{
x=a[i].q;
y=a[i].h;
}
else if(a[i].q<x)
{
ans+=y-x;
x=y;
y=a[i].h;
}
else
{
ans+=y-a[i].q;
x=y;
y=a[i].h;
}
}
cout<<ans;
fclose(stdin);
fclose(stdout);
return 0;
}