我正在对hackerrank(https://www.hackerrank.com/contests/w21/challenges/lazy-sorting)做一个问题,我很困惑为什么我的代码不符合要求。问题是:
洛根正在打扫他的公寓。特别是,他必须以非递减顺序对N个正整数排序他最喜欢的序列P.他在漫长的一天中感到疲惫,所以他发明了一种简单的方法(在他看来)做这项工作。他的算法可以通过以下伪代码来描述:while isNotSorted(P) do {
WaitOneMinute();
RandomShuffle(P)
}
您能否确定Logan等待分类的预计分钟数?
输入格式:
第一行包含一个整数N,表示置换的大小。第二行包含N个以空格分隔的整数,用于描述序列当前顺序中的各个元素,P_0,P_1 ...... P_N- 1。
约束: 2 <= N <= 18 1&lt; = P_i&lt; = 100
输出格式:
打印预期的分钟数Logan必须等待P进行排序,四舍五入到小数点后6位(即1.234567格式)。
示例输入:
2
5 2
示例输出:
2.000000
解释
随机shuffle后有两种可能的排列,每种排列的概率为0.5。在第一分钟之后获得序列的概率是0.5。在第二分钟之后将被分类的概率是0.25,概率将在第三分钟之后被分类为0.125,依此类推。因此预期的分钟数等于:
i * 2 ^ -i的总和,其中i从1变为无穷大= 2
我用c ++编写了我的代码如下:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
map <int, int> m; //create a map to store the number of repetitions of each number
int N; //number of elements in list
//calculate the number of permutations
cin >> N;
int j;
int total_perm = 1;
int temp;
for (int i = 0; i < N; i++){
cin >> temp;
//if temp exists, add one to the value of m[temp], else initialize a new key value pair
if (m.find(temp) == m.end()){
m[temp] = 1;
}else{
m[temp] += 1;
}
total_perm *= i+1;
}
//calculate permutations taking into account of repetitions
for (map<int,int>::iterator iter = m.begin(); iter != m.end(); ++iter)
{
if (iter -> second > 1){
temp = iter -> second;
while (temp > 1){
total_perm = total_perm / temp;
temp -= 1;
}
}
}
float recur = 1 / float(total_perm);
float prev;
float current = recur;
float error = 1;
int count = 1;
//print expected number of minutes up to 6 sig fig
if (total_perm == 1){
printf("%6f", recur);
}else{
while (error > 0.0000001){
count += 1;
prev = current;
current = prev + float(count)*float(1-recur)*pow(recur,count-1);
error = abs(current - prev);
}
printf("%6f", prev);
}
return 0;
}
我不太关心比赛,更多的是关于为我学习,所以如果有人能指出我错在哪里,我真的很感激。
答案 0 :(得分:0)
不幸的是我不熟悉C ++,所以我不确切知道你的代码在做什么。但是,我确实解决了这个问题。这是相当厚颜无耻的,我认为他们提出问题的方式只是让他们感到困惑。因此,这里的重要知识是,对于具有概率p的事件,预期的试验次数直到成功为1 / p。由于每次试验花费我们一分钟,这意味着我们可以找到预期的试验次数,并在最后添加“.000000”。
那你怎么做的?那么数字的每个排列都可能同样发生,这意味着如果我们能找到有多少排列,我们就可以找到p。然后我们拿1 / p来获得E [时间]。但请注意,每个排列的概率为1 / p,其中p是排列的总数。所以真的E [时间] =排列数。我把剩下的留给你了。
答案 1 :(得分:0)
这只是一个简单的问题。 这个问题看起来像bogo排序。 给定数组有多少独特的排列可能?在示例情况下,可能存在两种排列,因此任何一种排列发生的预期时间是2.000000。考虑到任何重复的数字,将此方法扩展到通用案例。
然而在问题中,数字可以重复。这减少了唯一排列的数量,从而减少了答案。
只需查找数组的唯一排列数,最多6位小数。这是你的答案。
考虑一下数组是否排序然后发生了什么?
E.g 如果测试用例是
5 5
5 4 3 2 1
然后ans将是120.000000(5!/ 1!)
5 5
1 2 3 4 5
然后你的问题中的ans将是0.000000。
5 5
2 2 2 2 2
然后ans也将是0.000000
5 5
5 1 2 2 3
然后ans是60.000000
一般情况下,如果数组没有排序:N!/ P!* Q!..等等..
这是另一个有用的链接:
https://math.stackexchange.com/questions/1844133/expectation-over-sequencial-random-shuffles