1067 Sort with Swap(0, i) (25分)
杂谈
对4错2后花了很多时间debug结果发现其实问题在一个低级错误。好气。
思路
首先得搞懂要得到最小值该怎么操作。
正确的操作方式是:
①如果0不在0位,那把它和该在它现在在的位置的数交换。这个操作每次能且只能让一个0以外的数归位。
②这样操作一定次数之后,0必然会回到0位。
③此时,如果还有数没有归位,那么0寻找一个没有被归位的数,和其交换。
④继续重复上述的①的操作。
如果0一开始就在0位而有数没归位,那不过是从②开头罢了。没有本质区别。
很显然,实际影响操作次数的只有①和③,而①操作要进行的次数与需要被归位的0以外的数相等。设其为k吧。而③要进行的次数,显然与是0回到0位的次数,也就是②相关。
那么0什么时候会回到0位呢?
以input为例,
3 5 7 2 6 4 9 0 8 1。
标上位置:0 1 2 3 4 5 6 7 8 9。
当7号位的0与2号位的7交换之后,下一个被交换的应该是谁?显然7的位置号,2。这个位置与值的关系有点像链表,位置就是这个数的“next”。然后就会发现,这个序列中有两个环,一个是0→7→2→3→0,另一个是5→1→9→6→4→5。
现在回到0什么时候会回到0位的问题。
0与第一个环中的各个数字依序交换、将第一个环的其他数放到该放的位置后,自己也回到了它该回的位置:0。也就是情况②出现。而下一步,③,则会让它进入第二个环。在和第二个环中各个数字依序交换后,第二个环中所有数字,包括0,也就回到了该回的位置。
所以答案呼之欲出了——如果0一开始在一个环内,③进行的次数,就是环的数量-1;如果0一开始在环外,③进行的次数与环的数量相同。
再加上前述①进行的次数k,即是结果了。
代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct {
int num;
bool arrived;
}Num;
int main()
{
int n;
int i, temp, abnormalcount, circle, flag0;
cin >> n;
vector<Num> v;
Num num;
abnormalcount = 0;
circle = 0;
for (i = 0; i < n; i++)
{
cin >> num.num;
if (num.num == i)//这个计算条件下0不在原位时是被计算进的,这也是后面flag0在v[0].num!=0时为-1的原因。
{
num.arrived = true;
}
else
{
num.arrived = false;
abnormalcount++;
}
v.push_back(num);
}
if (v[0].num == 0)
flag0 = 1;//对circle不应-1的补正
else
flag0 = -1;//对0不应被计入“需要被复位的次数”的补正
for (i = 0; i < n; i++)
{
if (v[i].arrived)
continue;
temp = i;
while (!v[temp].arrived)
{
v[temp].arrived = true;
temp = v[temp].num;
}
circle++;
}
cout << abnormalcount + flag0 + circle - 1;
cin >> i;
return 0;
}
题目
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 (≤10
5
) 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