uva331 - Mapping the Swaps

Mapping the Swaps

Sorting an array can be done by swapping certain pairs of adjacent entries in the array. This is the fundamental technique used in the well-known bubble sort. If we list the identities of the pairs to be swapped, in the sequence they are to be swapped, we obtain what might be called a swap map. For example, suppose we wish to sort the array A whose elements are 3, 2, and 1 in that order. If the subscripts for this array are 1, 2, and 3, sorting the array can be accomplished by swapping A2 and A3, then swapping A1 and A2, and finally swapping A2 and A3. If a pair is identified in a swap map by indicating the subscript of the first element of the pair to be swapped, then this sorting process would be characterized with the swap map 2 1 2.

It is instructive to note that there may be many ways in which swapping of adjacent array entries can be used to sort an array. The previous array, containing 3 2 1, could also be sorted by swapping A1 and A2, then swapping A2 and A3, and finally swapping A1 and A2 again. The swap map that describes this sorting sequence is 1 2 1.

For a given array, how many different swap maps exist? A little thought will show that there are an infinite number of swap maps, since sequential swapping of an arbitrary pair of elements will not change the order of the elements. Thus the swap map 1 1 1 2 1 will also leave our array elements in ascending order. But how many swap maps of minimum size will place a given array in order? That is the question you are to answer in this problem.

Input

The input data will contain an arbitrary number of test cases, followed by a single 0. Each test case will have a integer n that gives the size of an array, and will be followed by the n integer values in the array.

Output

For each test case, print a message similar to those shown in the sample output below. In no test case willn be larger than 5.

Sample Input
2 9 7
2 12 50
3 3 2 1
3 9 1 5
0
Sample Output
There are 1 swap maps for input data set 1.
There are 0 swap maps for input data set 2.
There are 2 swap maps for input data set 3.
There are 1 swap maps for input data set 4.

 

 

题意: 求通过交换相邻元素排序,求最少交换次数的方法有几种。

最少交换次数就是逆序对数,枚举交换方案即可。

另外,用冒泡排序的方法一定是交换次数最少的方案。

 

解法一: 枚举逆序对数减少的方案,到达有序序列的时候,就一定是最少交换次数的方案。 time: 0.015

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 10;
int n;
int a[maxn];
int ans;
bool isorder()
{
        for(int i=0;i<n-1;i++) if(a[i]>a[i+1]) 
                return false;
        return true;
}

void dfs(int d)
{
        if(isorder())
        {
                ans++; return;
        }

        for(int i=0;i<n-1;i++) if(a[i]>a[i+1])
        {
                swap(a[i], a[i+1]);
                dfs(d+1);
                swap(a[i], a[i+1]);
        }
}

int main()
{
#ifndef ONLINE_JUDGE
        freopen("./uva331.in", "r", stdin);
#endif
        int kase=0;
        while(scanf("%d", &n)==1 && n)
        {
                for(int i=0;i<n;i++) scanf("%d", a+i);
                ans=0;
                if(!isorder())
                        dfs(0);
                printf("There are %d swap maps for input data set %d.\n", ans, ++kase);
        }

    return 0;
}

解法二: 先求出逆序对数d,然后暴力枚举排序方案(控制深度为d),如果到达深度d时,序列变成有序序列,就找到一个最少交换次数的方案。 time: 0.059

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=10;
int n;
int inv, a[maxn], ans;
void dfs(int d)
{
    if(d==inv) {
        for(int i=0;i<n-1;i++) if(a[i]>a[i+1]) return;
        ans++;
    } else for(int i=0;i<n-1;i++) {
        swap(a[i], a[i+1]);
        dfs(d+1);
        swap(a[i], a[i+1]);
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("./uva331.in", "r", stdin);
#endif
    int kase = 0;
    while(scanf("%d", &n) == 1 && n) {
        for(int i=0;i<n;i++) scanf("%d", &a[i]);
        inv=0;
        for(int i=0;i<n;i++)
            for(int j=i+1;j<n;j++)
                if(a[i]>a[j]) inv++;
        ans=0;
        if(inv > 0) dfs(0);
        printf("There are %d swap maps for input data set %d.\n", ans, ++kase);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值