DA-Sort

本文介绍了DA-Sort算法,一种通过Delete-and-Append操作排序数组的方法。内容包括问题描述、输入输出格式、题意解释、解题思路以及代码实现。通过分析,提出了将序列分为已操作和未操作两部分的策略,以找到最小操作次数。
摘要由CSDN通过智能技术生成

欢迎访问https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~~

 

一、问题:

Description

You recently learned a new way to sort an array of numbers in your algorithms course. The algorithm sorts an array of numbers by repeatedly performing the Delete-and-Append operation. The Delete-andAppend operation consists of three steps: 1) Choose an element from the array. 2) Delete the chosen element from the array. 3) Append the chosen element to the end of the array. Being a curious student, you wonder what is the minimum number of Delete-and-Append operations required to sort a given array.

Input

The first line of input contains a single decimal integer P, (1 ≤ P ≤ 100), which is the number of data sets that follow. Each data set should be processed identically and independently. Each data set consists of two or more lines of input. The first line contains the data set number, K, followed by a single space, followed by an integer N, (1 ≤ N ≤ 1000), which is the length of the array to sort. The remaining lines in the dataset contains N positive integers that comprise the array to be sorted, 10 values per line, except for the last line which may have less than 10 values. All the array elements are no larger than 109 . The same value may appear more than once in the array to be sorted.

Output

For each data set there is one line of output. The single output line consists of the data set number, K, followed by a single space followed by an integer which is the minimum number of Delete-and-Append operations required to sort the array.

Sample Input

3

1 3

1 3 2

2 6

1 5 2 4 3 6

3 23

67890 56312 999999999 12345 23456

38927 45632 100345 98765 23456

87654 43278 23456 117654 321899

25432 54326 217435 26845 31782

33456 41234 56213

Sample Output

1 1

2 3

3 15

 

二、题意:

第一行数字 T 代表测试样例个数。

接下来的每个样例:

第一行的第一个数表示序号,第二个数表示序列有几个数。

第二行即为这个序列的数。

你可以对序列进行如下处理:

将序列中的某一个数拿到序列末尾 (即从原位置删除,再添加到序列末尾)。

求:至少拿几次,才能使得序列有序?

 

三、思路:

我们可以把序列分成为两部分,一部分为未被拿过的,一部分为被拿过的,为使操作次数最小,我们可以默认为被拿过的数都是有序的放在序列末尾的。其实我们只需要遍历查一遍,对于每一个数,它的后面是否存在比它小的数,若存在,则它必须被拿,这样遍历一遍后,我们可以保证这两部分分别都是有序的。但是要注意:这两部分合在一起并不一定有序的,比如第二个样例操作后我们得到的两部分是:1 2 3 6  ||   4 5,而6是比4和5大的。因此,我们只需记录一下被拿出的数的最小值,然后再从未拿出的序列里查一遍还有没有比它大的即可。

下面代码里a[ i ].x代表这个数的值,a[ i ].y用来标记这个数是否被拿过,拿过即为1,未拿过即为0 。

 

四、代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
#define read(x) scanf("%d",&x)
#define mem(a,b) memset(a,0,sizeof(a))
#define fori(a,b) for(int i=a;i<=b;i++)
#define forj(a,b) for(int j=a;j<=b;j++)
using namespace std;

struct A
{
    int x, y;
};

int main()
{
    int T, x, y, ans, min1;
    read(T);
    while(T--)
    {
        ans = 0, min1 = inf;
        scanf("%d %d", &x, &y);
        struct A a[y];
        mem(a, 0);
        fori(0, y-1)
            read(a[i].x);
        fori(0, y-2)
            forj(i+1, y-1)
                if(a[i].x > a[j].x)
                {
                    a[i].y = 1;
                    min1 = min(min1, a[i].x);
                    ans++;
                    break;
                }
        fori(0, y-1)
            if(a[i].x > min1 && a[i].y == 0)
                ans++;
        printf("%d %d\n", x, ans);
    }
    return 0;
}

 

欢迎访问https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~~

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值