1067. Sort with Swap(0,*) (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 (<=105) 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 1Sample Output:
9
https://www.patest.cn/contests/pat-a-practise/1067
https://www.nowcoder.com/pat/5/problem/4118
思路:
从任意乱序的位置开始找
如 f(a0)= a1 ,然后 f(a1)= a2,f(a2)= a3。。以此类推可以找到f(a(n-1))= a0,即形成一个环。
如果0 在这个环中,则
1、设 a0 = 0,f(0)= a1,即 a1 在第0个位置
2、将 a1 放到 合适的位置(即第a1个位置),即 f(a1)处。取出f(a1)的原值,记为 a2
3、将 a2 放到 第 a2 个位置,再将f(a2)的原值取出,记为a3
4、将 a3 放到 第 a3 个位置,以此类推,必有f(a(n-1))=0
5、将 0 放回 第 0 个位置,结束。
以上共有n个元素,共经过了n-1次操作
即,含0的n个元素的环,共移动n-1次。
如果0不在这个环中,则将0加入环中。
令f(0)=a0,f(a(n-1))=0;
则转化成了上述问题
共有n+1个元素,移动n次,在加上0入环的操作,共n+1次。
即,原环n个元素,移动n+1次。
即,不含0的n个元素的环,共移动n+1次。
根据上述规律,对原序列进行搜索,对于搜出的每一个环进行计算。
CODE:
#include<iostream>
#include<cstring>
using namespace std;
int arr[100100];
bool f[100100];
int main()
{
memset(f,0,sizeof(f));
int n;
cin>>n;
for (int i=0;i<n;i++)
{
cin>>arr[i];
}
int sum=0;
for (int i=0;i<n;i++)
if (f[i]==0)
if (arr[i]!=i)
{
int t=i;
int ori=arr[i];
int fl=0;
while (1)
{
//cout<<t<<" "<<arr[t]<<" "<<sum<<endl;
f[t]=1;
if (arr[t]==0) fl=1;
t=arr[t];
sum++;
if (arr[t]==ori) break;
}
if (fl==1) sum--;
else
sum++;
}
cout<<sum;
return 0;
}