洗牌问题(多种解法以高效解法)

Knuth公平洗牌算法(给一个数组随机排序) 洗牌算法的重要原则就是“全面”而且“公平”,并且要使用尽可能小的时间复杂度来实现。 什么叫公平呢?一旦你开始思考这个问题,其实答案不难想到。洗牌的结果是所有元素的一个排列。一副牌如果有 n 个元素,最终排列的可能性一共有 n! 个。公平的洗牌算法,应该能等概率地给出这 n! 个结果中的任意一个。 如思考到这一点,我们就能设计出一个简单的暴力算法了:对于 n 个元素,生成所有的 n! 个排列,然后,随机抽一个。 这个算法绝对是公平的。但问题是,复杂度太高。复杂度是多少呢?O(n!)。因为,n 个元素一共. 阅读详情
/*
洗牌问题

 

设2n张牌分别标记为1, 2, ..., n, n+1, ..., 2n,初始时这2n张牌按其标号从小到大排列。经一次洗牌后,原来的排列顺序变成n+1, 1, n+2, 2, ..., 2n, n。即前n张牌被放到偶数位置2, 4, ..., 2n,而后n张牌被放到奇数位置1, 3, ..., 2n-1。可以证明对于任何一个自然数n,经过若干次洗牌后可恢复初始状态。现在你的的任务是计算对于给定的n的值(n≤10^5),最少需要经过多少次洗牌可恢复到初始状态。 

 

输入输出格式

 

输入数据由多组数据组成。每组数据仅有一个整数,表示n的值。

 

对于每组数据,输出仅一行包含一个整数,即最少洗牌次数。 

 

样例输入

 

10

 

样例输出

 

6


*/

NO.
1 直接用一个一维数组模拟,速度超慢,代码如下:

#include 
<stdio.h>
#define MAX 20002

int main(void)
{
    
int a[MAX]={0},n2;
    
int i,j,k,n,t,total=0;
    scanf(
"%d",&n) ;
    n2 
=n*2 ;
    
for(i=1 ; i<= n2 ; i++)
    a[i] 
= i ;
    
    
while (1)
    
{
    
for(i=n+1,k=1; i<= n2 ; i++,k+=2)
    
{
  
     t 
= a[i] ; 
     
     
for(j=i-1 ; j>= k ; j--)
     a[j
+1] = a[j] ;
     a[k] 
= t ;
     
/*for(j=1 ; j<= n2 ; j++)
    printf("%d ",a[j]);
    printf(" ");
*/

    }

    total 
++ ;
    
if ( a[1] == 1)
    
break ;
    }

    
     printf(
" total = %d ",total);
    system(
"pause");
    
    
return 0 ;
}



NO.
2 用两个一维数组模拟,速度大大提高:代码如下:

#include 
<stdio.h>
#include 
<time.h>

#define MAX 20002

int main(void)
{
    clock_t end,begin ;
    
int a[MAX]={0},b[MAX],n2;
    
int i,j,k,n,t,total=0;
    scanf(
"%d",&n) ;
    begin 
= clock();
    n2 
=n*2 ;
    
for(i=1 ; i<= n ; i++)
    a[i] 
= i ;
    
for(j=n+1,i=1; j<= n2 ; j++,i++)
    b[i] 
= j ;
     
    
while (1)
    
{
        
        
for(i=n,j=n; i>= 1; i--,j--)
        
{
                t
= i+i ;
                a[t] 
= a[i] ;
                a[t
-1]=b[j] ;
        }

        
        
for(i=n+1,j=1; i<= n2 ; j++,i++)
        b[j] 
= a[i] ;
        
       
        total 
++ ;
         
        
if ( a[1] == 1)
        
break ;
        
    }

    
    printf(
"total = %d ",total);
    end 
= clock();
    printf(
"%d has cost %lf seconds!!! ",n,(double)(end-begin)/CLOCKS_PER_SEC);
    system(
"pause");
    
    
return 0 ;
}


NO.
3 找规律,然后简化过程,你会发现:其它只要1还原了,那么其它的也会还原,因此只要找到1还原时停止就OK了

/*
这题目,比较经典,找规律的,只要找到a[1] = 1 时停止就OK了。。。。
简写程序如下:
*/

#include 
<stdio.h>

int main(void)
{
    
int total=1,a1=2; /*找到了第一个位置第一次出现1时就停止,此时即洗牌完成*/
    
int n,k;
    scanf(
"%d",&n) ;
    
    k 
= n<<1 ; 
    
while ( a1 != 1)
    
{
          
if(a1 <= n)
          a1 
<<= 1 ;
          
else
          a1 
= (a1<<1)-k-1 ;
          
          total 
++;
    }

    
    printf(
"%d ",total) ;
     
    
return 0;
}
 
 
手把手教你学Simulink——机器人力控场景实例:基于Simulink的永磁同步电机重力补偿力矩控制仿真 本文介绍了基于Simulink的机器人重力补偿力矩控制仿真方法。针对机器人悬停时电机发热、抖动等问题,提出通过前馈补偿重力转矩的解决方案。文章详细阐述了从机器人动力学建模、重力补偿计算、PMSM转矩控制到系统集成的完整实现流程,并以2-DOF机械臂为例验证了补偿效果。结果表明,重力补偿能显著降低电机电流和拖拽力,提高系统柔顺性。文中还提供了高级功能扩展方向,如参数辨识、摩擦补偿等,为实际工程应用提供了参考框架。 阅读详情

相关推荐

【SLAM】SVO2.0编译运行和论文代码解读

SVO2是我遇到的最难编译的代码了,可能公开版本不能放太鲁棒的代码吧,搞了快一个星期,终于跑起来了。

iwanderu的博客 5973

FOJ Problem 1062 洗牌问题

Problem Description 设2n张牌分别标记为1, 2, ..., n, n+1, ..., 2n,初始时这2n张牌按其标号从小到大排列。经一次洗牌后,原来的排列顺序变成n+1, 1, n+2, 2, ..., 2n, n。即前n张牌被放到偶数位置2, 4, ..., 2n,而后n张牌被放到奇数位置1, 3, ..., 2n-1。可以证明对于任何一个自然数n,经过若干次洗牌后可

ShiWaiGaoRen12345的博客 1478

手把手教你用Simulink搭建DSOGI-PLL模型(附完整代码下载)

本文详细介绍了在Simulink中搭建高鲁棒性DSOGI-PLL模型的完整工程实践指南。针对传统锁相环在非理想电网下的不足,文章深入剖析了双二阶广义积分器锁相环(DSOGI-PLL)的核心原理与优势,并提供了从模块构建、系统组装到参数整定与测试验证的全流程手把手教程,附有完整代码下载,助力工程师应对谐波、电压跌落等复杂电网工况。

weixin_29223603的博客 388

洗牌问题(25分) FZU - 1062

设2n张牌分别标记为1, 2, ..., n, n+1, ..., 2n,初始时这2n张牌按其标号从小到大排列。经一次洗牌后,原来的排列顺序变成n+1, 1, n+2, 2, ..., 2n, n。即前n张牌被放到偶数位置2, 4, ..., 2n,而后n张牌被放到奇数位置1, 3, ..., 2n-1。可以证明对于任何一个自然数n,经过若干次洗牌后可恢复初始状态。现在你的的任务是计算对于给定的n

相似的人适合一起打闹 406

芯片设计新手必看:5分钟搞懂工艺角(Process Corner)到底是什么,为啥仿真总要用它?

本文详细解析了芯片设计中的工艺角(Process Corner)概念及其在仿真中的重要性。通过类比马拉松运动员的性能差异,解释了晶体管制造过程中的天然波动,并介绍了TT/FF/SS等工艺角代码的含义。文章还探讨了为何需要跑全工艺角仿真,以及现代芯片验证的完整流程,包括PVT矩阵和多模式分析(MMMC),帮助芯片设计新手快速掌握这一关键概念。

weixin_28713947的博客 244

51单片机STC8G1K08驱动ws2812记录

使用51单片机控制17个2812灯,这里选择STC8芯片,最大频率可以达到35M,参考网上的各种文章案例,使用定时器做的时候实测做不到规格书要求的245-345ns,STC8G1K08不带PWM,所以只能使用nop来做,好在单片机在这里只有做编程灯的功能,省略测试过程,下面是程序,使用的是24MHz内部晶振 //设置一个灯珠 void SendOnePix(unsigned char *ptr) { unsigned char i,j; unsigned char temp; fo...

的博客 7320

洗牌问题(C语言实现)

Description 给你2N张牌,编号依次为1~2n。这也是最初的牌的顺序。 每一次洗牌首先将所有牌分成上下两堆,每堆n张牌,然后将两堆牌依次交叉重合在一起。 比如第一次洗牌时,前面一堆的n张牌的编号依次为1~n,后面一堆的n张牌的编号依次为n+1~2n,后面一堆牌的第一章在最上面,将2堆牌交叉重合后的序列变为n+1,1,n+2,2,n+3,3,n+4,4..2n,n。 可以证明,对于任意自然数N,都可以在经过M次洗牌后第一次重新得到初始的顺序。 编程对于小于10000的自然数N,求出M的

m0_61892085的博客 4549

三菱FX5U PLC与CCLINK模块通信配置全流程(附接线图与参数详解)

本文详细解析了三菱FX5U PLC与CCLINK模块的通信配置全流程,包括硬件接线规范、参数设置及软件编程方法。通过实战指南帮助工程师快速掌握FX5U与CCLINK模块的高效通信技术,提升工业自动化控制系统的稳定性和可靠性。

weixin_27014595的博客 428

完美洗牌问题学习笔记

可以将扑克牌的数量增加 8 张,相当于每种花色多了 2 张牌,这时扑克牌的总数是 60 张,套入上面的算法可以求得经过 58 次完美洗牌后,60 张牌会和未洗牌的顺序一样。上面的分析是基于 0 ~ 51 的编号,也就是和原始的扑克牌花色点数没有关系,任意 52 张扑克牌做了 8 次完美洗牌后,都会恢复到原始的序位。总结上面的算法,得到模数公式如下,设需要经过 n + 1 次完美洗牌后,一副 m 张扑克牌的排序变为原始排序, m 为偶数。第 6 次各个数据的间隔变为 2 的 2 次方;

殇尘的博客 2993

26、遥感图像无监督变化检测方法解析

本文详细解析了遥感图像中的无监督变化检测方法,重点介绍了基于快速模糊 C-均值聚类的无监督变化检测方法(CDFFCM)在滑坡映射中的应用。CDFFCM 方法利用图像结构信息和高斯金字塔技术,提高了检测的准确性,减少了参数数量,并缩短了计算时间。该方法通过与传统方法的对比,展现出在高分辨率遥感图像滑坡检测中的显著优势。此外,文章还探讨了 CDFFCM 的未来发展趋势,包括技术融合、多模态数据应用以及智能化与自动化方向。

game4的博客 149

R语言数据可视化:绘制世界地图的两种方案

本文介绍了两种使用R语言绘制世界地图的方案:包含边界边框和不包含边界边框。无论您选择哪种方案,使用ggplot2包和相关的地理数据包,我们可以轻松地绘制出漂亮的世界地图。R语言提供了丰富的包和函数,使我们能够轻松地绘制世界地图,并根据需求添加边界边框。在本文中,我将介绍两种绘制世界地图的方案:一种包含边界边框,一种不包含边界边框。在上述代码中,我们使用了与方案一相同的数据准备和地图绘制步骤,但省略了添加边界边框的代码。函数的调用,我们可以绘制不包含边界边框的世界地图。方案二:绘制不包含边界边框的世界地图。

CodeMaven的博客 2225

算法:完美洗牌问题

有个的数组{a1,a2,a3,…,an,b1,b2,b3,…,bn},希望排序后{a1,b1,a2,b2,….,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法。

OceanStar的博客 631

《手把手教你YOLOv9实战》,改进专栏目录

为了提供友好的操作效果,本专栏将会手把手搭建可视化界面,我将用PyQt5 搭建一个可视化界面,可视化界面能够实现基本的图像加载与检测功能,如支持视频、摄像头,还支持更换不同的 YOLOv9 模型,并适应不同领域(如口罩检测系统、人脸检测系统、工业缺陷检测系统等),界面灵活、功能强大。通过YOLOv9加以改进设计,形成新的算法框架,一起水科研和论文,专栏会一直持续更新中,本专栏适合目标检测、分割、分类。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 2154

洗牌问题( HDU - 1210 )

  洗牌问题  HDU - 1210  Eddy是个ACMer,他不仅喜欢做ACM题,而且对于纸牌也有一定的研究,他在无聊时研究发现,如果他有2N张牌,编号为1,2,3..n,n+1,..2n。这也是最初的牌的顺序。通过一次洗牌可以把牌的序列变为n+1,1,n+2,2,n+3,3,n+4,4..2n,n。那么可以证明,对于任意自然数N,都可以在经过M次洗牌后第一次重新得到初始的顺序。编程对于...

WMY的博客 441

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

程序员编程艺术第三十四~三十五章:格子取数问题,完美洗牌算法

程序员编程艺术第三十四~三十五章:格子取数问题,完美洗牌算法 分类: 11.TAOPP(编程艺术) 13.TAOPP array2013-08-23 12:04 9561人阅读 评论(44) 收藏 举报 目录(?)[+] 第三十四~三十五章:格子取数,完美洗牌算法 作者:July、caopengcs、绿色夹克衫。致谢:西芹_n

pi9nc的专栏 2092

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

完美洗牌算法

题目有个长度为2n的数组{a1,a2,a3,…,an,b1,b2,b3,…,bn},希望排序后{a1,b1,a2,b2,….,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法。来源2013年UC的校招笔试题思路一第①步、确定b1的位置,即让b1跟它前面的a2,a3,a4交换:a1,b1,a2,a3,a4,b2,b3,b4 12第②步、接着确定b2的位置,即让b2跟它前面的a3,...

dongyu_1989的博客 261

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法

LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法

yinying293的博客 435

完美洗牌问题(数组间数据有规律的交叉)

题目详情:有个长度为2n的数组{a1,a2,a3,…,an,b1,b2,b3,…,bn},希望排序后{a1,b1,a2,b2,….,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法。问题描述 解法一蛮力变换 1步步前移 2中间交换 解法二完美洗牌算法 1位置置换pefect_shuffle1算法 2分而治之perfect_shuffle2算法 3完美洗牌算法perfect_shu

梦里水乡的专栏 4984

【20190826】【查漏补缺】洗牌算法_生成随机数(Knuth Shuffle洗牌算法实现)

问题 设计一个公平的洗牌算法。 什么叫公平?假如有 n 张牌,那么这 n 张牌共有 n!个排列方式(很简单的排列组合思想),所以洗牌中“公平”是指,系统能随机的输出这 n!个结果中的任意一个。暴力解法思想很简单,但时间复杂度很高O(n!),下面学习一下 Knuth Shuffle 洗牌算法,思想也很简单。 Knuth Shuffle 算法从高位到低位进行,依次从前面的元素中随机(用到了ran...

诗小葵的博客 516

洗牌程序c语言原理,C语言经典算法 - 洗牌算法

下面是编程之家 jb51.cc 通过网络收集整理的代码片段。编程之家小编现在分享给大家,也给大家做个参考。说明:洗扑克牌的原理其实与乱数排列是相同的,都是将一组数字(例如1~N)打乱重新排列,只不过洗扑克牌多了一个花色判断的动作而已。解法:初学者通常会直接想到,随机产生1~N的乱数并将之存入阵列中,后来产生的乱数存入阵列前必须先检查阵列中是否已有重复的数字,如果有这个数就不存入,再重新产生下一个数...

weixin_39609953的博客 754

【bzoj1965】【AHOI2005】洗牌

题意   有一副牌,共nn张(nn为偶数),每一次洗牌将其均分为上下两叠,然后取下叠第一张为新的第一张,上叠第一张为新的第二张,下叠第二张为新的第三张……求经过mm次洗牌后,第ll张牌的面值(初始为【1,n】【1,n】) 解法 模拟:   这道题比较容易,只要能够一步一步地分析下去:   首先可以知道,对于现在处于第xx张的牌来说,有:

清疚的博客 421

Ahoi2005 洗牌 扩展欧几里得

Ahoi2005 洗牌问题描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动。 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小联提议用扑克牌打发长途旅行中的无聊时间。玩了几局之后,大家觉得单纯玩扑克牌对于像他们这样的高智商人才来说太简单了。有人提出了扑克牌的一种新的玩法。 对于扑克牌的一次洗牌是这样定义的,将一叠N(

rgnoH的博客 392

洗牌算法

题目 有个长度为2n的数组{a1,a2,a3,…,an,b1,b2,b3,…,bn},希望排序后{a1,b1,a2,b2,….,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法。 来源 2013年UC的校招笔试题 思路一 第①步、确定b1的位置,即让b1跟它前面的a2,a3,a4交换: a1,b1,a2,a3,a4,b2,b3,b4 第②

smilesundream的博客 536

面试必看:优势洗牌

本文介绍了一种贪心算法结合双指针的策略来解决优势洗牌问题。该方法首先对两个输入数组进行排序预处理,然后采用逆序遍历和双指针匹配的方式,确保每一步都选择最优的匹配方案。算法时间复杂度为O(n log n),空间复杂度为O(n),能够高效处理大规模数据。核心思想是保留原数组索引信息,并通过贪心策略最大化优势匹配数,同时最小化优质元素的浪费。该方案简洁高效,适用于各类常规测试场景。

2501_90114783的博客 442

【数论】【欧拉函数】【快速幂】洗牌机

3333: 洗牌机 时间限制:2 Sec内存限制:512 MB 题目描述 有2n张牌,放在2n个从1到2n的有序位置上。洗牌机每次可以把第i张牌洗到p(i)的位置上。P(i)的定义如下: 问经过最少多少轮洗牌,才会使所有牌回到原来的位置。 输入 输入格式: 有多组数据,每组数据一个整数n(n<=109) 输出 输出格式: 对于每组数据,输出一个整数,表...

weixin_30569001的博客 72
上一篇: (阶乘末尾0的个数的求法)求1~N中因子的数量的方法
下一篇: 字符串匹配问题 kmp算法C语言实现
oopos
博客等级 码龄19年 21粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值