全排列+顺序对问题

题目描述

牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。

输入描述:

每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。

输出描述:

输出一行表示合法的排列数目。

示例1

输入

5 5
4 0 0 2 0

输出

2

代码如下:

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

/********************************************************************************
*输入一个数组,返回此数组中顺序对的数量
*********************************************************************************/
int getDuishu(vector<int> &array)
{
    int num = 0;
    for (int i = 0; i < array.size() - 1; i++)
    {
        for (int j = i + 1; j < array.size(); j++)
        {
            if (array[i] < array[j])
            {
                num++;
            }
        }
    }
    return num;
}

/********************************************************************************
将整个数组分为两部分:
1、第一部分由不为零的数字组成,pos1存储这些不为零的
数字在原序列中的位置信息。
2、第二部分为由0组成的未知序列,pos2存储相应的位置信息。
*********************************************************************************/
int getNum(vector<int> &array1, vector<int> &pos1, vector<int> &array2, vector<int> &pos2)
{
    int num2 = getDuishu(array2);
    int num3 = 0;
    for (int i = 0; i < array1.size(); i++)
    {
        for (int j = 0; j < array2.size(); j++)
        {
            if ((array1[i] > array2[j]) && (pos1[i] > pos2[j]))
            {
                num3++;
            }
            else if ((array1[i] < array2[j]) && (pos1[i] < pos2[j]))
            {
                num3++;
            }
        }
    }
    return num2 + num3;
}

/********************************************************************************
全排列用
do
{
}while(next_permutation(array.begin(),array.end()))
注意在全排列钱应该使用sort函数将数组从小到大进行排序。
*********************************************************************************/
int main()
{
    int n;
    cin >> n;
    int k;
    cin >> k;
    int *array1 = new int[n];
    vector<int> temp1;
    vector<int> temp1pos;
    vector<int> temp2;
    vector<int> temp2pos;
    for (int i = 0; i < n; i++)
    {
        cin >> array1[i];
        if (array1[i] != 0)
        {
            temp1.push_back(array1[i]);
            temp1pos.push_back(i);
        }
        else
        {
            temp2pos.push_back(i);
        }
    }
    for (int i = 1; i <= n; i++)
    {
        bool label = false;
        for (int j = 0; j < temp1.size(); j++)
        {
            if (i == temp1[j])
            {
                label = true;
                break;
            }
        }
        if (label == false)
        {
            temp2.push_back(i);
        }
    }
    sort(temp2.begin(), temp2.end());
    int num1 = getDuishu(temp1);
    int rightnum = 0;
    do
    {
        int tempNum = getNum(temp1, temp1pos, temp2, temp2pos) + num1;
        if (tempNum == k)
        {
            rightnum++;
        }
    } while (next_permutation(temp2.begin(), temp2.end()));
    cout << rightnum << endl;
}

不知为什么只有80%的通过率,您的代码已保存运行超时:您的程序未能在规定时间内运行结束,请

检查是否循环有错或算法复杂度过大。case通过率为80.00%

猜你喜欢

转载自blog.csdn.net/TI09257/article/details/81208421
今日推荐