您的位置:首页 > 其它

codeforces 733E

2016-11-01 20:26 218 查看

题目大意

有n级台阶,每一级台阶有一个符号U或D。

假如你在第i级台阶,符号是U,那么你下一步会在i+1,反之则在i−1.

假如你在某个时刻离开了第i级台阶,那一位的标识符就会翻转,U变成D,D变成U。

问你从每一级台阶开始走,直到离开楼梯(可以下端或上端),需要多少时间?

解题思路

首先假如有cntu个U,cntd个D,那么你从最上端的cntu级台阶开始走,一定最后从上方走出,反之则从下方走出。

证明:

假如在从上往下数第x,x≤cntu个,其包括其上方共有y个U.

你会发现一个事实,假如我最后要从上方走出,那么我这个位置上方(包括自己)的D的数量小于等于自己下方U的数量。

即 x−y≤cntu−y

x≤cntu

得证。

然后呢?

假如某个位置上方有个D,但是他要从上方离开,会出现什么情况。

假如序列是这样的:

UUDDUDUDU

我要从第5格出发。

8个时刻过后

UDDDUUUDU

而且回到了第5格。

看看交换了什么,从上往下第4格以及从上往下第4个U。

8个时刻意味着什么?

从上往下第4格以及从上往下第4个U位置差*2。

因为每个位置都经过了两边,所以,只有两个位置交换符号,其他不变。

接着就一直交换,直到这个位置往上都是U。

答案就是,交换的代价+最后全U往上的代价。

D同理。

参考代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define maxn 1000005
#define ll long long
using namespace std;

int n;

char s[maxn];

int a[maxn];

ll ans[maxn];

int main(){
scanf("%d",&n);
fo(i,1,n) {
char c=getchar();
while (c!='U' && c!='D') c=getchar();
s[i]=c;
}
a[0]=0;
fo(i,1,n) if (s[i]=='D') a[++a[0]]=i;
ll tot=0;
fo(i,1,a[0]) {
tot+=(a[i]-i) * 2;
ans[i]=i+tot;
}
a[0]=0;
fd(i,n,1) if (s[i]=='U') a[++a[0]]=i;
tot=0;
fo(i,1,a[0]) {
int w=n-i+1;
tot+=(w-a[i]) * 2;
ans[w]=i+tot;
}
fo(i,1,n) printf("%lld ",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces