题意:给出两个字符串A、B,只包含大写字母。每次交换A中相邻的两个字符,最少经过多少次变换可以变成字符串B,保证有解
两眼就可做的水题,水水更健康~
第一眼,答案妥妥的逆序对
第二眼,因为只包含大写字母所以一些位置上的字母是一样的,但是没有关系,因为同样的字符一定是按照顺序一一对应的,处理一下就可以了
然后归并排序或树状数组求逆序对
注意开long long
type
rec=record
last:longint;
end;
var
n :longint;
i :longint;
ans :int64;
s1,s2 :ansistring;
pre,a,c :array[0..1000010] of longint;
num :array['A'..'Z'] of rec;
procedure merge_sort(l,r,mid:longint);
var
t,i,j:longint;
begin
i:=l; j:=mid+1; t:=l;
while (t<=r) do
begin
if (i<=mid) and ((a[i]<=a[j]) or (j>r)) then
begin
c[t]:=a[i];
inc(i);
inc(t);
end else
begin
c[t]:=a[j];
inc(ans,mid-i+1);
inc(j);
inc(t);
end;
end;
for i:=l to r do a[i]:=c[i];
end;
procedure merge(l,r:longint);
var
mid:longint;
begin
if (l<>r) then
begin
mid:=(l+r)>>1;
merge(l,mid);
merge(mid+1,r);
merge_sort(l,r,mid);
end;
end;
begin
readln(n);
readln(s1);
readln(s2);
for i:=1 to n do
begin
if (num[s1[i]].last<>0) then pre[i]:=num[s1[i]].last;
num[s1[i]].last:=i;
end;
for i:=n downto 1 do
begin
a[i]:=num[s2[i]].last;
num[s2[i]].last:=pre[num[s2[i]].last];
end;
//
merge(1,n);
writeln(ans);
end.
——by Eirlys