NOIP2013火柴排隊

2021-08-09 21:19:38 字數 1837 閱讀 9185

思路

首先易知,當a,b兩串都進行過排序後,各對應位置的差值平方之和最小。

簡單證明:

設序列只有兩個數分別是a,b;c,d;且a < b;c < d

設s1=(a-c)^2+(b-d)^2,s2=(a-d)^2+(b-c)^2,

s1-s2=2ad+2bc-2ac-2bd=2a(d-c)+2b(c-d)=2(c-d)(b-a)<0

s1 < s2。

若存在a=b或c=d的情況s1仍為最小距離。

那麼問題就轉化成了,已知a串 b串對應位置,每次交換b中相鄰的兩個數,求最小的移動步數使b串各位置與a串一一對應。

交換過程類似於氣泡排序,我們知道氣泡排序每次交換都會使原串逆序對數減少1,則交換次數 = b串相對於a串的逆序對數(以a串對應b串位置的大小關係為比較標準)。統計逆序對數即可。

**

//歸併排序求逆序對——o(nlogn)ac

#include

#include

#include

#include

#include

using

namespace

std;

const

int mod = 99999997;

int n,ans1,ans2;

int a[1000010],b[1000010],as[1000010],bs[1000010],mp[1000010],pos[1000010],tmp[1000010];

void merge_sort(int l,int r)

else tmp[k++]=b[i++];

}while(i<=mid)

tmp[k++]=b[i++];

while(j<=r)

tmp[k++]=b[j++];

for(int i=l;i<=r;i++)

b[i]=tmp[i];

}int main()

for(int i=1;i<=n;i++)

sort(as+1,as+n+1);

sort(bs+1,bs+n+1);

for(int i=1;i<=n;i++)

merge_sort(1,n);

printf("%d",ans2);

return

0;}

//氣泡排序求逆序對——o(n^2)會導致tle

#include

#include

#include

#include

#include

using

namespace

std;

const

int mod = 99999997;

int n,ans1,ans2;

int a[1000010],b[1000010],as[1000010],bs[1000010],mp[1000010],pos[1000010];

bool flag;

void bubble_sort(int l,int r)

}if(!flag)

break;

flag=0;

}}int main()

for(int i=1;i<=n;i++)

sort(as+1,as+n+1);

sort(bs+1,bs+n+1);

for(int i=1;i<=n;i++)

bubble_sort(1,n);

printf("%d",ans2);

return

0;}

NOIP2013 火柴排隊

題目 分析 a中第幾大一定對應b中第幾大。ab同時移動相當於a移動,相對位置不變。所以,用c i 表示a i 需要移動到的 位置,求其中的逆序對。因為乙個每移動相鄰兩個元素相當於消除乙個逆序對。include include using namespace std const int tmax 10...

NOIP 2013 火柴排隊

題目描述 description 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 其中 ai表示第一列火柴中第 i 個火柴的高度,bi表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可...

noip2013 火柴排隊

涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 ai bi 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交換,請你通...