1067 Sort with Swap(0, i) (25分)
Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order. But what if Swap(0, *)
is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:
Swap(0, 1) => {4, 1, 2, 0, 3}
Swap(0, 3) => {4, 1, 2, 3, 0}
Swap(0, 4) => {0, 1, 2, 3, 4}
Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.
Input Specification:
Each input file contains one test case, which gives a positive N (≤) followed by a permutation sequence of {0, 1, ..., N−1}. All the numbers in a line are separated by a space.
Output Specification:
For each case, simply print in a line the minimum number of swaps need to sort the given permutation.
Sample Input:
10
3 5 7 2 6 4 9 0 8 1
Sample Output:
9
题目分析:看浙大《数据结构》的时候见到过这题 重做并没有做成功 运行超时了 我想的是每次通过0与0的位置来归位 若0在这个过程中不小心被交换到了0的位置 那就得将0交换到还未被归为的那个元素上 思路是对的 做法导致时间复杂度过大
通过上面的分析 可以将0所在的看成一个环 只需要记录环中有多少元素 以及有多少环 当0所在的环计算完成后 就到另一个环去
过了3个测试点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <climits> 3 #include<iostream> 4 #include<vector> 5 #include<queue> 6 #include<map> 7 #include<set> 8 #include<stack> 9 #include<algorithm> 10 #include<string> 11 #include<cmath> 12 using namespace std; 13 int Address[100001]; 14 int Array[100001]; 15 void swap(int i, int j)//交换2个地址上的值 i,j为地址 16 { 17 Address[Array[i]] = j; 18 Address[Array[j]] = i; 19 int temp = Array[i]; 20 Array[i] = Array[j]; 21 Array[j] = temp; 22 } 23 int main() 24 { 25 int N; 26 int times = 0; 27 cin >> N; 28 for (int i = 0; i < N; i++) 29 { 30 cin >> Array[i]; 31 Address[Array[i]] = i; 32 } 33 int flag = 1; 34 while (flag) 35 { 36 if (Address[0] == 0){ 37 for (int i = 1; i < N; i++) 38 if (Address[i] != i) { 39 swap(Address[0], Address[i]); 40 flag = 1; 41 times++; 42 break; 43 } 44 else flag = 0; 45 } 46 else{ 47 swap(Address[0], Address[Address[0]]); 48 times++; 49 } 50 } 51 cout << times; 52 }
全过
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 4 int A[100000] = { 0 }; 5 int Position[100000] = { 0 }; 6 int IsRight[100000] = { 0 }; 7 void Swap(int i, int j) 8 { 9 int tmp = A[i]; 10 A[i] = A[j]; 11 A[j] = tmp; 12 } 13 int SwapTimes=0; 14 int FindElements(int Pos) 15 { 16 int num=1; 17 while (Position[Pos]!=Pos) 18 { 19 num++; 20 IsRight[Position[Pos]] = 1; 21 Position[Pos] = Position[Position[Pos]]; 22 } 23 return num; //返回元素的个数 24 } 25 void Charge(int N) 26 { 27 int num; 28 //从零开始计算 29 SwapTimes += FindElements(0)-1; //交换次数比元素个数少一 30 for (int i = 1; i < N; i++) 31 { 32 if (!IsRight[i]) 33 SwapTimes += FindElements(i)+1; //虽然交换次数比元素个数少一 但是要利用0来进行交换 所以时 这个环的元素加一 34 } //而把0元素添加到 环中先进行一次交换 所以 最后结果为 元素+1-1+1 35 } 36 int main() 37 { 38 int N; 39 scanf("%d", &N); 40 for (int i = 0; i < N; i++) 41 { 42 int num; 43 scanf("%d", &num); 44 A[i] = num; 45 Position[num] = i; 46 if (A[i] == i) 47 IsRight[i] = 1; 48 } 49 Charge(N); 50 printf("%d", SwapTimes); 51 return 0; 52 }