数的全排列

假如给你三个数字123,要求你进行数字的全排列,你会怎么做?
简单的思路:用三个for循环,采用枚举法,再用条件进行判断。
什么是枚举法?
将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,合适就保留,不合适就丢弃。例如:找出1到100之间的素数,需要将1到100之间的所有整数进行判断。
枚举算法因为要列举问题的所有可能的答案,所有它具备以下几个特点:
1、得到的结果肯定是正确的;
2、可能做了很多的无用功,浪费了宝贵的时间,效率低下。
3、通常会涉及到求极值(如最大,最小,最重等)。
4、数据量大的话,可能会造成时间崩溃。

代码如下:# include <stdio.h>
int main(void)
{
int i,j,k;
for(i=1;i<=3;i++)
{
for(j=1;j<=3;j++)
{
for(k=1;k<=3;k++)
{
if(i!=j && i!=k && j!=k)
{
printf("%d%d%d\n",i,j,k);
}
}
}
}
return 0;
}
如果有5个,6个,无非就是多用几个for循环,放心,电脑还撑得住,但是如果有时间限制的情况下,那我们怎么用代码去实现呢?之前我们讲到深度优先搜索,这时候就可以派上用场了!
深度优先搜索的代码基本功能如下:
void dfs(int step)
{
判断边界
尝试每一种可能 for(i=1;i<=n;i++)
{
继续下一步 dfs(step+1);
}
返回
}

具体代码如下:# include <stdio.h>
int a[10],book[10],n;
void dfs(int step) //深度优先搜索的模型
{
int i;
if(step==n+1)
{
for(i=1;i<=n;i++)
{
printf("%d",a[i]);
}
printf("\n");
return ;
}

for(i=1;i<=n;i++)
{
	if(book[i]==0)
	{
		a[step]=i;
		book[i]=1;
		dfs(step+1);
		book[i]=0;            //这一步很重要,就是你放完了后你要记得返回之前的一步,这时你需要解除之前一步的数字以进行后来的数字安放
	}
}
return ;

}
int main(void)
{
scanf("%d",&n);
dfs(1);
getchar();getchar();
return 0;
}

很显然,深度优先搜索的优点就得以看出。再来一个题,你书中有九张从1到9的扑克牌,然后把这九张扑克放到九个盒子中并使得XXX+XXX=XXX成立。这时也可以用深搜来做,会比较简单。
跟之前的思路以及模型套路是一样的,先解决“当下该如何做”,至于下一步如何做“则与“当下如何做”是一样的。
代码如下:# include <stdio.h>
int a[10],book[10];
void dfs(int step)
{
int i;

if(step==10)
{
	if(a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]==a[7]*100+a[8]*10+a[9])
	{
		printf("%d%d%d+%d%d%d=%d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
	}
	return ;
}

for(i=1;i<=9;i++)
{
	if(book[i]==0)
	{
		a[step]=i;
		book[i]=1;
		dfs(step+1);
		book[i]=0;
	}
}
return ;

}
int main(void)
{
dfs(1);
getchar();
getchar();
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值