The puzzle HDU - 6489 (CF gym思维题)
题目描述
Kayaking is playing a puzzle game containing n different blocks. He marks the blocks with integers from 1 to n, which show the blocks’ original positions. Each time he can exchange two blocks and he wants to know how many times he needs at least to restore the puzzle.
输入
The input starts with one line contains exactly one positive integer T which is the number of test cases.
Each test case contains two lines.
The first line contains an integer, which indicates the number of puzzle pieces.
The second line contains n different integers, the i-th number means the mark of the block in the i-th position.
输出
For each test case, output one line with one number represents the minimum operations.
样例输入
2
4
2 3 4 1
4
2 1 4 3
样例输出
3
2
提示
1≤T≤20,1≤n≤100000
题意: 给出一个序列,一个操作,选择任意两个数做一次位置交换,需要交换几次使之有序。
原文链接:https://blog.csdn.net/kuronekonano/article/details/82820650
代码:
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <string> #include <cmath> #include <vector> #include <stack> #include <queue> #include <stack> #include <list> #include <map> #include <set> //#include <unordered_map> #define Fbo friend bool operator < (node a, node b) #define mem(a, b) memset(a, b, sizeof(a)) #define FOR(a, b, c) for (int a = b; a <= c; a++) #define RFOR(a, b, c) for (int a = b; a >= c; a--) #define off ios::sync_with_stdio(0) #define sc(a) scanf("%d",&a) #define pr(a) printf("%d\n",a); #define SC(n,m) scanf("%d%d",&n,&m) bool check1(int a) { return (a & (a - 1)) == 0 ? true : false; } using namespace std; typedef pair<int, int> pii; typedef long long ll; const int INF = 0x3f3f3f3f;//1e10 const int mod = 1e9 + 7; const int Maxn = 1e5 + 5; const int M = Maxn * 20; const double pi = acos(-1.0); const double eps = 1e-8; int vis[Maxn], a[Maxn]; int main() { off; int t; cin >> t; while (t--) { mem(vis, 0); int n; cin >> n; FOR(i, 1, n) { cin >> a[i]; } int ans = 0; FOR(i, 1, n) { int cnt = 0; while (!vis[i] && a[i] != i) { //找下一个自己该在的位置 cnt++; vis[i] = 1; //标记环中该值是否被遍历过 i = a[i]; cout << a[i] << endl; } if (cnt)ans += cnt - 1;//每个环的交换次数求和 } cout << ans << endl; } return 0; }

浙公网安备 33010602011771号