有 \(n\) 個瓶子,編號 \(1∼n\),放在架子上。
比如有 \(5\) 個瓶子:
2 1 3 5 4
要求每次拿起 \(2\) 個瓶子,交換它們的位置。
經過若干次後,使得瓶子的序號為:
1 2 3 4 5
對於這麼簡單的情況,顯然,至少需要交換 \(2\) 次就可以復位。
如果瓶子更多呢?你可以通過程式設計來解決。
第一行包含乙個整數 \(n\),表示瓶子數量。
第二行包含 \(n\) 個整數,表示瓶子目前的排列狀況。
輸出乙個正整數,表示至少交換多少次,才能完成排序。
資料範圍
\(1≤n≤10000,\)
輸入樣例1:
5
3 1 2 5 4
輸出樣例1:3
輸入樣例2:5
5 4 3 2 1
輸出樣例2:2
環,置換群將 \(a_i\) 連向位置為 \(a_i\) 上的整數,即 \(a_\),其構成 \(k\) 個環,最後一定是形成 \(n\) 個自環,而對於每個環內的整數,交換會增加乙個環,交換不同環的兩個整數會合併即減少乙個環,所以最後至少進行 \(n-k\) 次即能形成 \(n\) 個自環
貪心可以想到乙個貪心策略:從 \(i\in 1\sim n\) 列舉,如果不在對應位置上,則將 \(i\) 所在位置和當前數交換,即上述在環內交換兩數
// problem: 交換瓶子
// contest: acwing
// url:
// memory limit: 64 mb
// time limit: 1000 ms
// // powered by cp editor (
// %%%skyqwq
#include //#define int long long
#define help
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long ll;
typedef pairpii;
template bool chkmax(t &x, t y)
template bool chkmin(t &x, t y)
template void inline read(t &x)
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}int res,n,a[10005],b[10005];
int main()
for(int i=1;i<=n;i++)
if(a[i]!=i)
cout#define help
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long ll;
typedef pairpii;
template bool chkmax(t &x, t y)
template bool chkmin(t &x, t y)
template void inline read(t &x)
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}int res,n,cnt,a[10005];
bool v[10005];
int main()
cout
}
AcWing1224 交換瓶子
題 有 n 個瓶子,編號 1 n,放在架子上。比如有 5 個瓶子 2 1 3 5 4要求每次拿起 2 個瓶子,交換它們的位置。經過若干次後,使得瓶子的序號為 1 2 3 4 5對於這麼簡單的情況,顯然,至少需要交換 2 次就可以復位。如果瓶子更多呢?你可以通過程式設計來解決。本題思路比較精巧,需要用...
AcWing 1224 交換瓶子
tags 置換群 圖論目錄1 2345 3125 4每乙個點都有屬於他的環。交換操作 某點的出度,會指向和他交換的點的下標 所以最少要交換的次數,就是每次都讓環內的點交換 for int j i st j j b j b b j 某一點下標對應的值,當成另外乙個的下標 b j 某一點下標對應的值 i...
藍橋 交換瓶子
交換瓶子 有n個瓶子,編號 1 n,放在架子上。比如有5個瓶子 2 1 3 5 4要求每次拿起2個瓶子,交換它們的位置。經過若干次後,使得瓶子的序號為 1 2 3 4 5 對於這麼簡單的情況,顯然,至少需要交換2次就可以復位。如果瓶子更多呢?你可以通過程式設計來解決。輸入格式為兩行 第一行 乙個正整...