cjweffort

博客园 首页 联系 订阅 管理

好弱啊,这个题目折腾了好久。

构造hash表用来维护各个元素所在的位置,利用map维护一颗红黑树来保存还未确定的元素的位置。

(1)用0不断的跟其他元素交换,每次交换都会保证一个元素在正确的位置。

(2)交换的过程中可能使得元素0到第0个位置,此时用0与某个还未在正确位置的元素交换。

循环(1)(2)直至所有元素都在正确的位置。

出现(2)这种情况的最大次数可能N,因为出现一次这种情况,一定会在接下来运行(1)的时候保证至少一个元素被交换到正确的位置。综上所述,最大交换次数应该不会高于2*N,每次交换会维护一次map,所以最终的算法复杂度应该为O(NlogN).

// 1067. Sort with Swap.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;

const int N = 100003;
int a[N], hashTab[N];
map<int, int> cmap; 

void swap(int &m1, int &m2){
	int temp = m1;
	m1 = m2; m2 = temp;
}

int main()
{
	int n, cnt = 0, diff;
	cin >> n;
	for(int i = 0; i < n; i++){
		cin >> a[i];
		hashTab[a[i]] = i;
		if(i != 0 && a[i] != i)
			cmap[i] = i;
	}
	do{
		while(hashTab[0] != 0){
			swap(a[hashTab[0]], a[hashTab[hashTab[0]]]);
			int tmp = hashTab[0]; 
			hashTab[0] = hashTab[hashTab[0]];
			hashTab[tmp] = tmp;
			map<int, int>::iterator mIte = cmap.find(tmp);
			cmap.erase(mIte);
			cnt++;
		}
		if(cmap.size() != 0){
			map<int, int>::iterator mIte = cmap.begin();
			cnt++;
			hashTab[0] = hashTab[mIte -> first];
			hashTab[mIte -> first] = 0;
			swap(a[hashTab[mIte -> first]], a[0]);
		}
	} while(cmap.size() != 0);
	cout << cnt << endl;
	return 0;
}

改进版本:

弃用map,维护一个bool数组used[]保存某个元素是否已经确定好,每当一个元素被确定下来,就赋值为true(初始时数组清0)。

设置一个在第2步可以被用来交换的位置swapPos,初始时swapPos=1,由某个元素确定下来,就要询问该位置是否和swapPos相等,如果相等,则相应的swapPos后移直至一个还未确定好的位置pos(即used[pos]==false)。由此观之,swapPos后移顶多后移N个位置,每次在第二步寻找与0交换的元素,可以直接用a[swapPos]与之交换。所以最终的算法复杂度应为O(3*N)。

// 1067. Sort with Swap.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;

const int N = 100003;
int a[N], hashTab[N];
bool used[N];

void swap(int &m1, int &m2){
	int temp = m1;
	m1 = m2; m2 = temp;
}

int main()
{
	int n, cnt = 0;
	cin >> n;
	memset(used, 0, sizeof(used));
	for(int i = 0; i < n; i++){
		cin >> a[i];
		hashTab[a[i]] = i;
		if(a[i] == i)
			used[i] = true;
	}
	int swapPos = 1;
	while(used[swapPos])
		swapPos++;
	do{
		while(hashTab[0] != 0){
			swap(a[hashTab[0]], a[hashTab[hashTab[0]]]);
			int tmp = hashTab[0]; 
			hashTab[0] = hashTab[hashTab[0]];
			hashTab[tmp] = tmp;
			used[tmp] = true;
			if(tmp == swapPos){
				swapPos++;
				while(used[swapPos])
					swapPos++;
			}
			cnt++;
		}
		if(swapPos != n){
			cnt++;
			hashTab[0] = hashTab[swapPos];
			hashTab[swapPos] = 0;
			swap(a[hashTab[swapPos]], a[0]);
		}
	} while(swapPos != n);
	cout << cnt << endl;
	return 0;
}

posted on 2013-10-10 19:52  cjweffort  阅读(255)  评论(0编辑  收藏  举报