参考博客:传送门
51nod 1574
这题主要考虑到要形成一个循环节,循环节的长度实际是一个环的长度。
#include <bits/stdc++.h>
using namespace std;
#define LL __int64
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i < n; ++i)
const int qq = 2e5 + 10;
int num[qq];
bool vis[qq];
int main(){
int n; scanf("%d", &n);
for(int i = 1; i <= n; ++i){
int x; scanf("%d", &x);
num[x] = i;
}
LL ans = 0;
for(int i = 1; i <= n; ++i){
int x; scanf("%d", &x);
ans += abs(i - num[x]);
}
printf("%I64d\n", ans / 2);
return 0;
}
Codeforces 584E
参考:传送门
#include <bits/stdc++.h>
using namespace std;
#define LL __int64
#define pb push_back
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i < n; ++i)
#define pill pair<int, int>
const int qq = 2000 + 10;
int num[qq], stand[qq];
int a[qq], b[qq];
bool vis[qq];
vector<pill> vt;
int main(){
int n; scanf("%d", &n);
for(int i = 1; i <= n; ++i){
int x; scanf("%d", &x);
stand[x] = i;
}
for(int i = 1; i <= n; ++i){
int x; scanf("%d", &x);
num[stand[x]] = i;
}
for(int i = 1; i <= n; ++i){
printf("%d ", num[i]);
}
puts("");
int ans = 0;
while(true){
int pos = -1;
for(int j = 1; j <= n; ++j){
if(num[j] != j && (pos == -1 || num[j] < num[pos])){
pos = j;
}
}
if(pos == -1) break;
while(num[pos] != pos){
for(int j = pos - 1; j >= 1; --j){
if(num[j] >= pos){
vt.pb(pill(j, pos));
swap(num[pos], num[j]);
ans += pos - j;
pos = j;
break;
}
}
}
}
printf("%d\n%d\n", ans, (int)vt.size());
for(int i = 0; i < (int)vt.size(); ++i){
printf("%d %d\n", vt[i].first, vt[i].second);
}
return 0;
}