331 - Mapping the Swaps(回顾+ dfs)

331 - Mapping the Swaps(回溯+ dfs)

题目:331 - Mapping the Swaps


题目大意:给出一个序列,要求只能相邻的进行交换,求交换次数最少的不同的交换方式有多少种。

解题思路:每次都可以从头选两个需要交换的位置进行交换,(只有前一个的值大于后一个的值才需要交换),选的第一个交换的数的位置不一样,所对应的map也是不一样的。然后这里有可以剪枝的地方:如果在交换的过程中交换的次数已经大于之前的最小的交换次数就可以不用在扩展下去了。注意:如果出现更小的交换次数需要把map的次数改为1.然后扩展需要用到回溯,需要状态的恢复才能产生多种可能。


#include<stdio.h>
#include<algorithm>
using namespace std;

const int N = 5;
int t, s[N], count1, min1, order[N];

void swap (int i, int j) {

	int temp = s[i];
	s[i] = s[j];
	s[j] = temp;
}

bool equal () {
	
	bool flag = 1;
	for (int i = 0; i < t; i++)
		if (s[i] != order[i]) {

			flag = 0;
			break;
		}
	return flag;
}

void handle (int num) {

	if (num > min1)
		return;
	if (equal()) {
	
		if (num == min1)
			count1++;
		else if (num < min1) {

			count1 = 1;
			 min1 = num;
		}
		return;
	}
	for (int i = 0; i < t - 1; i++) {
		
		if ( s[i] > s[i + 1]) {

			swap(i,  i + 1);
			handle (num + 1);
			swap(i,  i + 1);
		}	
	}
}

int main () {
	 
	int n = 0;
	while (scanf("%d", &t), t) {
	
		for (int i = 0; i < t; i++) 
			scanf("%d", &s[i]);
		for (int i = 0; i < t; i++)
			order[i] = s[i];
		sort(order, order + t);
		count1 = 0;
		if (!equal()) {

			min1 = 100;
			handle(0);
		
		}
//		printf("%d\n", min1);
		printf("There are %d swap maps for input data set %d.\n", count1, ++n);
	}
	return 0;
}