JZOJ-senior-5958. 【NOIP2018模擬11.8A組】祕密郵件
阿新 • • 發佈:2018-11-09
Time Limits: 1000 ms Memory Limits: 524288 KB
Description
小 A 收到了一封來自外星球的祕密郵件。郵件由 n 個大寫英文字母組成,不巧的是小A 收到郵件以後一不小心打亂了原來的字母順序。但是聰明的小 A 記住了原郵件的完整內容,現在她每次可以選擇打亂後的郵件中相鄰的兩個字母進行交換,問最少交換多少次能夠將打亂的郵件恢復成原郵件。
Input
第一行一個整數 n 表示郵件的長度。
第二行一個長度為 n 的只包含大寫字母的字串表示打亂後的郵件。
第三行一個長度為 n 的只包含大寫字母的字串表示原郵件。
為保證打亂後的郵件可以恢復成原郵件,所有的測試資料滿足任意一種大寫字母在兩封郵件中的出現次數相同。
Output
共一行包含一個整數,表示最少的交換次數
Sample Input
4
ABCD
DBCA
Sample Output
4
【樣例說明】
第一次交換第一個和第二個字母得到 BACD;第二次交換第二個和第三個字母得到BCAD;第三次交換第三個和第四個字母得到 BCDA;第四次交換第二個和第三個字母得到BDCA;第五次交換第一個和第二個字母得到 DBC
Data Constraint
Solution
按
串中字母出現的順序給
串標號,然後求逆序對個數
記得開
!!!
Code
#include<algorithm>
#include<cstdio>
#include<vector>
#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 ll long long
using namespace std;
const int N=1e6+5,M=30;
int n,a[N],a1[N],c[M],d[M];
ll ans;
char s[N],t[N];
vector<int> v[M];
void msort(int l,int r)
{
if(l==r) return;
int m=(l+r)>>1;
msort(l,m);
msort(m+1,r);
int i=l,j=m+1,k=l;
while(i<=m&&j<=r)
{
if(a[i]>a[j]) a1[k]=a[j],++k,++j,ans+=m-i+1;
else a1[k]=a[i],++k,++i;
}
while(i<=m) a1[k]=a[i],++i,++k;
while(j<=r) a1[k]=a[j],++j,++k;
fo(o,l,r) a[o]=a1[o];
}
int main()
{
freopen("letter.in","r",stdin);
freopen("letter.out","w",stdout);
scanf("%d%s%s",&n,s+1,t+1);
fo(i,1,n)
{
int x=t[i]-'A'+1;
v[x].push_back(i),++c[x];
}
fo(i,1,n)
{
int x=s[i]-'A'+1;
a[i]=v[x][d[x]++];
}
msort(1,n);
printf("%lld",ans);
}