Sorting by Swapping POJ - 1674(变相排序)

先说说题目想让我们干什么:
给定一个从1到n的数字排列,我们总是可以通过交换数字对来获得序列1,2,3,…,n 例如,如果初始序列为2、3、5、4、1,我们可以按以下方式对其进行排序:

2 3 5 4 1
1 3 5 4 2
1 3 2 4 5
1 2 3 4 5

在这里三个交换被用过。给定特定的排列,我们至少需要进行多少次交换。
https://vjudge.net/problem/POJ-1674

清楚题意了,这里给出两种做法:
一般思路是从头遍历,只要数字所在位置不对,我们在后面找到该位置主人与之交换,交换一次ans++即可
这里给出核心代码:

int ans = 0;
    for(int i = 1; i <= n ; i++) {
        if(a[i] == i) continue;
        for(int j = i + 1; ; j++)
            if(a[j] == i) {
                swap(a[i], a[j]);
                ans++; break;
            }
    }
/但效率是个问题,上述代码搜索时间过长,耗时 250ms
/下面给出另一种方法,耗时 < 50ms  核心代码如下:
int a[maxn], p[maxn];
int n; scanf("%d",&n);
for(int i = 1; i <= n; i++) {
   scanf("%d", &a[i]);
   p[ a[i] ] = i;//p 存 数字所在下标
}

int ans = 0;
for(int i = 1; i <= n ; i++)
   if(i != a[i]) {
       p[a[i]] = p[i];//注意p[i]无需同步,因为不会再用到
       swap(a[i], a[p[i]]);
       ans++;
   }
发布了54 篇原创文章 · 获赞 43 · 访问量 1962

猜你喜欢

转载自blog.csdn.net/Jungle_st/article/details/104630719