Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 正确洗牌:代码阻塞[2014]_Algorithm - Fatal编程技术网

Algorithm 正确洗牌:代码阻塞[2014]

Algorithm 正确洗牌:代码阻塞[2014],algorithm,Algorithm,我想和大家分享1A轮中的代码阻塞问题C,它叫做。我很想知道你的解决办法 问题是: 大小为N的排列是N个数字的序列,每个数字介于0和N-1之间,其中每个数字正好出现一次。它们可能以任何顺序出现 有许多大小为N的排列(精确地说是N阶乘,但在这个问题中并不重要)。有时我们只想随机选择一个,当然我们想均匀地随机选择一个:每个大小为N的排列都应该具有相同的被选择概率 以下是实现该目标的一种可能算法的伪代码(下面我们称之为“好算法”): 在上面的代码中,randint(a..b)返回a和b之间的统一随机整数

我想和大家分享1A轮中的代码阻塞问题C,它叫做。我很想知道你的解决办法

问题是:

大小为N的排列是N个数字的序列,每个数字介于0和N-1之间,其中每个数字正好出现一次。它们可能以任何顺序出现

有许多大小为N的排列(精确地说是N阶乘,但在这个问题中并不重要)。有时我们只想随机选择一个,当然我们想均匀地随机选择一个:每个大小为N的排列都应该具有相同的被选择概率

以下是实现该目标的一种可能算法的伪代码(下面我们称之为“好算法”):

在上面的代码中,randint(a..b)返回a和b之间的统一随机整数(包括a和b)

这里有同样的算法。我们从身份置换开始:从0到N-1的所有数字都以递增顺序写入。然后,对于0和N-1(含)之间的每个k,我们在k和N-1(含)之间选取一个独立的均匀随机整数pk,并将置换中位置k(基于0)处的元素与位置pk处的元素交换

这里有一个N=4的例子。我们从身份置换开始:

0 1 2 3
现在k=0,我们随机选取0到3之间的p0,包括0和3。假设我们选了2个。我们交换第0个和第2个元素,我们的排列变成:

2 1 0 3
2 0 1 3
2 0 3 1
现在k=1,我们在1和3之间随机选取p1,包括1和3。假设我们又选了2个。我们交换第一和第二元素,我们的排列变成:

2 1 0 3
2 0 1 3
2 0 3 1
现在k=2,我们在2和3之间随机选取一个p2,包括。假设我们选了3个。我们交换第二和第三个元素,我们的排列变成:

2 1 0 3
2 0 1 3
2 0 3 1
现在k=3,我们在3和3之间随机选取一个p3,包括。唯一的选择是3。我们交换第三和第三个元素,这意味着排列不会改变:

2 0 3 1
这个过程现在结束了,这是我们的随机排列

还有许多其他算法可以统一生成随机排列。然而,也有许多生成随机排列的算法,这些算法看起来与此算法非常相似,但并不一致——一些排列更可能由这些算法生成

这里有一个这种类型的糟糕算法。采用上面的好算法,但在每一步中,不要在k和N-1之间随机选取pk,而是让我们在0和N-1之间随机选取pk。这是一个很小的变化,但是现在一些排列比其他排列更可能出现

下面是该算法的伪代码(我们将在下面称之为坏算法):

在每个测试用例中,您将得到一个按以下方式生成的排列:首先,我们选择上面描述的好算法或坏算法,每个算法的概率为50%。然后,我们使用所选择的算法生成一个置换。通过观察排列,你能猜出选择了哪种算法吗

解决这个问题

这个问题对于代码阻塞来说有点不寻常。您将获得T=120个排列,每个排列N=1000个数字,并应打印每个排列的答案–这部分与往常一样。然而,你不需要得到所有正确的答案!如果您对至少G=109个案例的回答是正确的,您的解决方案将被视为正确的。但是,您必须遵循输出格式,即使在您的答案不正确的情况下也是如此。在任何情况下,唯一可能是错误的,但仍然允许你被判断为正确的事情,是以好换坏,或反之亦然;但是你仍然应该为每个案例打印好的或坏的

我们保证提供给您的排列是根据上述方法生成的,并且它们是独立生成的

这个问题涉及到随机性,因此可能发生的情况是,即使是最好的解决方案也无法对某个输入进行109次正确猜测,因为好的算法和坏的算法都可以生成任何排列。因此,这个问题没有大的输入,只有小的输入,如果你认为自己运气不好,可以再试一次。请注意,如果您以后解决了输入问题,即使您出错的唯一原因是偶然性,对于不正确的提交,通常会有4分钟的惩罚

在我们处理这个问题的经验中,确实发生了这种情况(只是因为偶然的机会而得到错误的答案);因此,如果您确信您的解决方案应该有效,但失败了,那么使用失败的解决方案重试可能是一种合理的策略

祝你好运

输入

输入的第一行给出了测试用例的数量T(总是120)。每个测试用例包含两行:第一行包含单个整数N(始终为1000),下一行包含N个空格分隔的整数-使用两种算法之一生成的置换

输出

对于每个测试用例,输出一行包含“case#x:y”,其中x是测试用例编号(从1开始),y是“GOOD”或“BAD”(不带引号)。如果您猜测排列是由问题陈述中描述的第一个算法生成的,则应输出“GOOD”;如果您猜测排列是由问题陈述中描述的第二个算法生成的,则应输出“BAD”

极限

T = 120
G = 109
N = 1000
排列中的每个数字将介于0和N-1(包括)之间,并且从0到N-1的每个数字将在排列中恰好出现一次

样品

Input 

2
3
0 1 2
3
2 0 1

Output 

Case #1: BAD
Case #2: GOOD


样本输入没有遵循问题陈述中的限制-实际输入将大得多。

在为所做的出色研究的基础上,下面的测试相当有效。计算索引k的数量,其中perm[k]>k。如果数字超过N/2+少量,则打印错误。否则,请打印好

这里