poj 1674 Sorting by Swapping

这是一道编程题,涉及到选择排序的优化。通过创建两个数组,一个存储原始序列,另一个存储目标序列。在遍历过程中,如果原始序列中的元素与目标序列不一致,则在原始序列中找到正确元素并交换,以此实现排序。这种方法适用于自定义目标序列,不仅限于升序排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sorting by Swapping
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 9698 Accepted: 5191

Description

Given a permutation of numbers from 1 to n, we can always get the sequence 1, 2, 3, ..., n by swapping pairs of numbers. For example, if the initial sequence is 2, 3, 5, 4, 1, we can sort them in the following way: 

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

Here three swaps have been used. The problem is, given a specific permutation, how many swaps we needs to take at least. 

Input

The first line contains a single integer t (1 <= t <= 20) that indicates the number of test cases. Then follow the t cases. Each case contains two lines. The first line contains the integer n (1 <= n <= 10000), and the second line gives the initial permutation.

Output

For each test case, the output will be only one integer, which is the least number of swaps needed to get the sequence 1, 2, 3, ..., n from the initial permutation.

Sample Input

2
3
1 2 3
5
2 3 5 4 1

Sample Output

0
3

Source


一道选择排序题目,但是用传统的选择排序写会超时,就像我第一次交这道题目一样,但是思维不应受限于选择排序,我们可以创建两个数组,一个存下要处理的序列(a数组),一个存下目标序列(b数组),a数组与b数组一一对比,在对比过程中如果不同则在a中找着应该放在这个位置的元素,进行交换,这样,从a的首元素一直到尾元素遍历一遍也就把a数组排成了b数组的模样。


PS:在这道题目中b数组所存序列是一个传统的升序,但是即使题目要求的是自定义的目标序列也是一样处理,升序只是一般情况中的一个特殊情况。

//Code:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=10005;
int a[maxn];
int b[maxn];

int main()
{
    //freopen("in.txt","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=i;
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]!=b[i])
            {
                for(int j=i+1;j<=n;j++)
                {
                    if(a[j]==b[i])
                    {
                        swap(a[i],a[j]);
                        ans++;
                        break;
                    }
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值