[转载]伯努利装错信封问题
(2016-12-29 22:40:30)
标签:
转载 |
今天是我一次写博客,之所以开这个博客也是受学长的启发,希望借这个博客好好整理一下,以后这里会有一些我认为有帮助的题目,有水题也有难题(可能对我来说),废话不说,直接说今天这道题。
这道题本质上就是全错排,我想很久都没有头绪,肯能是受装苹果问题的印象,一开始我就认为这是用递归做,这题大概下一篇博文我就很整理一下,受其影响,我认为也应该会是先确定一位,再一次往下推;
后来在群里听一些盆友的分析,知道了应该全排列,然后排除一些特殊的,怎么全牌呢?有两种思路,一个大概是放一个数组,这个数组表示一个数字,然后按数字的递增来表示全排列,另一种就是所谓的算法,显然我入了这个坑,,,虽然输出顺序有错,但细细想这个算法还是很赞的,事先声明,回溯法对此题并不受用,,,
后来高中同学给了我一个代码,在他的指点下,我写了这个代码
} //打印兼排除 //排除非错位的 //排除重复的 void fun(int *a,int index,int n){
|
后来,老师给我一个算法,这个算法竟然不用递归,简直极好的, #include
for(i=a;i |
#include
#include
int printed;
void draw( int * int k)
{
int i;
for (i=0;i
{
printf ( "%d" ,a[i]);
}
printf ( "n" );
}
void Settle( int *a, int iStep, int k)
{
int i;
for (i=0;i
if (a[iStep-1]==a[i]) return ;
if (iStep==k)
{
draw(a,k);
printed++;
}
for (i=1;i<=k;i++)
{
if (i==iStep+1) continue ;
a[iStep]=i;
Settle(a,iStep+1,k);
}
}
void main()
{
int *
int k;
scanf ( "%d" ,&k);
a=( int *) calloc (k, sizeof ( int ));
Settle(a,0,k);
printf ( "s=%dn" ,printed);
} |
总结:这种递归格式很值得推崇,代码的模块化显然也是这几个代码的共同的优势所在, |