蓝桥杯青少年创意编程大赛题解:不同数列的个数

题目描述

一个数列 P P P 中有 n n n 个数。小蓝从中选择位置连续的 k k k 个数,并对这 k k k 个数进行升序排列。求排序后的数列有多少种?

输入描述

n   k n\ k n k

P 0   P 1 . . . P n − 1 P_0\ P_1...P_{n-1} P0 P1...Pn1

其中: 所有的输入都是整数, P 0 , P 1 , . . . . . . , P n − 1 P_0,P_1,......,P_{n-1} P0,P1,......,Pn1数值都不相同。​

输出格式

部分排序后数列的排列数。

数据范围

2 ≤ n ≤ 100 2 \le n \le 100 2n100
2 ≤ k ≤ n 2\le k\le n 2kn
0 ≤ P i ≤ n − 1 0\le P_i\le n-1 0Pin1

输入样例

5 3
0 2 1 4 3

输出样例

2

提示
从原数列抽取连续3个数排序后有2种可能性: ( 0 , 1 , 2 , 4 , 3 ) (0,1,2,4,3) (0,1,2,4,3) ( 0 , 2 , 1 , 3 , 4 ) (0,2,1,3,4) (0,2,1,3,4)

算法思想

题中给出的数据范围较小,因此可以使用暴力枚举的方式:枚举数列中所有连续的 k k k 个数的组合,然依次对每一个进行排序。

但是排序后可能后产生重复的数列。例如:对于输入样例 [ 02143 ] [0 2 1 4 3] [02143] [ 021 ] [0 2 1] [021] [ 214 ] [2 1 4] [214]进行排序,得到的数列都是 [ 01243 ] [01243] [01243]

继续分析,由于数列中数值都不相同,所以排序后只可能在相邻两项中产生相同结果。因此只需记录上次产生的数列,然后和本次的排序结果进行比较即可。

时间复杂度

O ( n 2 l o g n ) O(n^2logn) O(n2logn)

代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 110;
//b记录本次排序后的数列
//last记录上次排序得到的数列
int a[N], b[N], last[N];
int n, k;
//检查两个数列是否相同
bool check(int a[], int b[])
{
    for(int i = 0; i < n; i ++)
        if(a[i] != b[i]) return false;
    return true;
}

int main()
{
    cin >> n >> k;
    for(int i = 0; i < n; i ++) cin >> a[i];
    //将原数列a拷贝到last中
    memcpy(last, a, sizeof a);
    int sum = 0;
    //枚举所有连续k个数的起始位置
    for(int i = 0; i <= n - k; i ++)
    {
    	//将a拷贝到b中进行排序
        memcpy(b, a, sizeof a);
        sort(b + i, b + i + k);
        //排序后与上一个序列不相同
        if(!check(last, b)) sum ++;
        //将b拷贝到last
        memcpy(last, b, sizeof b);
    }
    cout << sum << endl;
   return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少儿编程乔老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值