问题 A: 字母交换
时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]
题目描述
某正教授级特级教师获得了一段古老的文字,全部由 26 个大写英文字母组成。他产生了一个疯狂的想法,即想把这段文字中所有字母按 A 到 Z 的顺序排序,即所有 A 放在开头,然后跟着所有 B,再是所有 C,最后是所有 Z。比如原
字符串为“HELLOWORLD”,排序后应变为“DEHLLLOORW”。但是特教毕竟领着国务院的特殊津贴,于是他还有一个要求,即排序时每次只能交换相邻两个字母。现在他想知道最少交换多少次能完成排序?
输入
仅一行,包含一个仅含大写字母的长度为 L 的字符串(注意 L 不输入)。
输出
共一行,包含一个整数表示最少交换次数。
样例输入 Copy
【样例1】
LSDSL
【样例2】
HELLOWORLD
样例输出 Copy
【样例1】
4
【样例2】
16
提示
对于50%的数据,1≤L≤2000;
对于100%的数据,1≤L≤2×106
有点归并的感觉https://blog.csdn.net/QXK_Jack/article/details/104105406
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char str[2000005],t[2000005];
ll ans=0;
void Merge(int l,int mid,int r)
{
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r)
{
if(str[i]<=str[j])
{
t[k++]=str[i++];
}
else
{
t[k++]=str[j++];
ans+=(mid-i+1);
}
}
while (i<=mid) t[k++] = str[i++];
while (j<=r)t[k++] =str[j++];
for(int s=l;s<=r;s++)
str[s]=t[s];
}
void merge_sort(int l,int r)
{
if(l<r)
{
int m=(l+r)>>1;
merge_sort(l,m);
merge_sort(m+1,r);
Merge(l,m,r);
}
}
int main()
{
scanf("%s",str);
int len=strlen(str);
merge_sort(0,len-1);
cout<<ans;
return 0;
}