您的位置:首页 > 其它

1067. Sort with Swap(0,*) (25)

2015-08-02 20:09 459 查看
题目如下:

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 1

Sample Output:
9


题目要求从一个由0到N-1的数据组成的线性表中,只允许进行0和*交换,来完成升序排序。

一个自然的思路,就是让0把正确的元素换到自己的位置,例如开始0在8位置,则把8换过来,让原来8的位置换成0,这样多次重复就可完成元素的归位。需要注意的是,中途可能出现0出现在0位的情况,例如0在3号位,而3恰好在0号位,则0到了0位置,但是排序并未结束。

这时候应该让0和最近的一个错误位置元素交换,然后继续上面的过程。

还有个关键的问题是判断排序的结束, 注意到上面需要用到错误位置的元素,因此设计一个函数每次从位置1开始找错误元素,如果找不到返回0,注意不要从0开始找,这样只要找到的位置不是0,则说明还有未完成排序的元素,如果从0开始找,就无法判断是否排序结束了,因为我们用0判断是否找不到,并且我们不必担心第一个错误位置是0的情况,这个属于0在0位置但排序未完成的情况,在下面有处理。

上面说的比较乱,总结如下:

①从位置1开始查找错误位置,找不到返回0,找到返回相应位置。

②如果查找函数返回0,说明排序结束,直接结束,否则进入③。

③如果0已经归位,但是排序没有结束,如果0不动无法继续排序,这时候让0和上面得到的错误位置交换,这个交换属于无用交换,但必须进行。

④在0没有归位的情况下,不断地把0的位置和应该在这个位置的元素交换,直到0归位,这时候再通过①的查找判断是否结束,没有结束则再继续③、④,直到满足找不到错误位置。

下面的代码来自tiantangrenjian

#include <stdio.h>

int findNotOK(int* arr,int begin,int end)	//从begin开始往后寻找未到位的数
{
	for(int i=begin;i<end;i++)
	{
		if(arr[i]!=i)return i;
	}
	return 0;
}

int main()
{
    int n;
	scanf("%d",&n);
	int* arr = new int
;
	int i,t;

	for(i=0;i<n;i++)
	{
		scanf("%d",&t);
		arr[t]=i;
	}
	int tmp = 0;
	int count=0;
	int firstPos = 1;
	firstPos = findNotOK(arr,firstPos,n);

	while(firstPos)		//还有未到位的数字
	{
		if(arr[0]==0)		//如果0到位了,则与未到位的firstPos交换
		{
			arr[0] = arr[firstPos];
			arr[firstPos] = 0;
			count++;
		}

		while(arr[0]!=0)	//如果0不到位,则循环与自己所指向的值交换
		{
			tmp = arr[0];
			arr[0] = arr[tmp];
			arr[tmp] = tmp;
			count++;
		}
		firstPos = findNotOK(arr,firstPos,n);		//此时0归位了,找到下一个未到位的数字
	}
	printf("%d\n",count);

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: