介紹
逆序對 - 如果存在l<r,並且a[l]<a[r],則稱為一個逆序對。
在穩定排序情況下,逆序對的個數等於相鄰數交換的次數。(可以說是冒泡的次數)
至於你說你氣泡排序,歸併排序(後面要用)都不太會建議去看看,鄙人的文章
各種排序集合
ps:並不是打廣告,這是為了您好.)逃
個人看法
相信很多人跟 以前的我 一樣認為逆序對不難,歸併排序一下就出來了,多簡單啊!
但我想說,簡單是簡單,但是大部分題目你都看不出來,所以 偶 才寫了這篇文章
題目
P5149 會議座位
題目描述
話說校長最近很喜歡召開全校教職工大會,讓老師們強行聽他裝逼
現在校長在校園網上公佈了一份座位表,\(n\) 位老師從左到右依次排成一行。老師們都對這個座位很滿意。
然而到了開會時,校長不小心把座位表打亂了,老師們很不滿。老師們並不在意自己的位置變了多少,但如果有一對老師 \(a\) 和 \(b\),他們原來的座位是 \(a\) 在 \(b\) 左邊,現在變成了 \(a\) 在 \(b\) 右邊,那麼這一對老師便會有一單位不滿值。
校長想知道這些老師的總不滿值是多少。
輸入介紹
第一行一個正整數 \(n\),為 \(n\) 位老師。
第二行有 \(n\) 個字串,每個字串代表老師的名字(大小寫敏感)。這一行代表原來的座位表。
第三行有 \(n\) 個字串,代表打亂後的座位表。
輸出介紹
一行,一個正整數,表示老師們的總不滿值。
輸入輸出樣例
樣例1:
3 1
Stan Kyle Kenny
Kyle Stan Kenny
樣例2:
5 3
A B C D E
B A D E C
解析
只要看清本質就會了,就是求逆序對
用歸併排序就可以了
程式
由於個人 馬 蜂 不好看所以用一個"盆友"的
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
string s;
int n,a[N],b[N];
long long ans;
map<string,int>m;
void merge_sort(int left,int right)
{
if(left>=right) return;
int mid=(right-left)/2+left;
merge_sort(left,mid);
merge_sort(mid+1,right);
int i=left,j=mid+1,k=left;
while(i<=mid&&j<=right)
{
if(a[i]<a[j]) b[k++]=a[i++];
else b[k++]=a[j++],ans+=mid-i+1;
}
while(i<=mid) b[k++]=a[i++];
while(j<=right) b[k++]=a[j++];
for(int i=left;i<=right;i++)
a[i]=b[i];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>s;
m[s]=i;
}
for(int i=1;i<=n;i++)
{
cin>>s;
a[m[s]]=i;
}
merge_sort(1,n);
printf("%lld",ans);
return 0;
}