1067 Sort with Swap(0, i) (25分)

Given any permutation of the numbers {0, 1, 2,..., N1}, 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, ..., N1}. 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个测试点
 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 }
View Code

全过

 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 }
View Code
原文地址:https://www.cnblogs.com/57one/p/12068723.html