火柴问题 +全排列

/*有N(N<=24)个火柴棒,希望拼出形如A+B=C的等式 等式中的A,B,C均是火柴拼出来的数
0--9的数字下图所示

现在有N个火柴棒 希望能拼出等式比如:
N=14 能拼出1+1=1 和 1+0=1
N=18 可拼出0+4=4 0+11=11 1+10=11 2+2=4 7+2=9 10+1=11 11+0=11 4+0=4 2+7=9 共九种
注意 + = 各需要两根火柴棒 
如果A!=B 则 A+B  与B+A看作两个不等的式子  所有的火柴必须全用上
对于现在的N个火柴能拼出多少等式呢 
时间限制 1S
解:既然是找到形如A+B=C的式子 最简单的例子就是枚举
接下来的主要问题就是 A B C的枚举范围是什么呢?我们只需要在0---1111之间枚举即可
 因为题目说N<=24 除去 + = 共四根火柴棒 还剩下最多20 而0-9这些数字中只有1用的火柴最少 这样
20根火柴 最多会组成10个1 因此A+B=C这个等式 中 A B C 中的任何一个数都不会超过1111
代码 复杂度O(N^2) */
# include <stdio.h>
int gainint(int *p,int a,int b);//*P范围[a,b]
# define M 1111
# define Q 24
int NUM(int X);
int main(){
    int A,B,C,N,sum=0;
	printf("请输入火柴的总数[6--%d]:",Q);  //输入火柴总数
	gainint(&N,6,Q);
   for(A=0;A<M;A++)
      for(B=0;B<M;B++)
	  {
	    C=A+B;
		if(NUM(A)+NUM(B)+NUM(C)==N-4) //判断是否找到一解
		{
		   printf("%d+%d=%d\n",A,B,C);
		   sum++;
		}
	  }
    printf("一共可以拼出%d种不同的等式.",sum);
	getchar();
}
int gainint(int *p,int a,int b)//*P范围[a,b]
{
	int c[2]={0,1};
	do{
	  scanf("%d",p);
	  while(getchar()!='\n');  
       if(*p>b||*p<a)
	   printf("输入有误,请重新输入(%d--%d):",a,b);
	}while(*p>b||*p<a);
    return *p;
}
int NUM(int X)
{
	int POW[]={6,2,5,5,4,5,6,3,7,6},sum=0;//用数组来记录0--9这10个数字的每个数字需要用的火柴个数
	while(X/10)   //循环中要留下最后的个位
	{
	   sum+=POW[X%10];
	   X/=10;
	}
    return sum+POW[X];  //NUM+个位的数 因为个位数可能为0
}
全排列
/*输入数字N 输出1---N的全排列
EG:N=3  
123 
231
312
321
132
213   相当于深度优先 代码由注释*/
# include <stdio.h>
# define N 9    //几位数 
void DFS(int A[2][N],int M,int step);//A为二维数组 初始化为0 M为A种用的数组长度 step用于递归
int main(){
	int A[2][N]={0};//A[0]存放数字 A[1]存放标志
	int n;
	printf("输入N(1---%d):",N);
	scanf("%d",&n);
	DFS(A,n,0);
	return 0;
}
void DFS(int A[2][N],int M,int step)//递归
{
	int i;
    if(step==M)    //如果前M个已经排好 此时赢直接输出 并停止递归
	{
	    for(i=0;i<M;i++)
			printf("%d",A[0][i]);
		return;    //如果没有return  程序会无休止的循环下去
	}
	for(i=0;i<M;i++)
	{
	    if(!A[1][i])   //当此前的数字没有在函数中使用
		{
		   A[0][step]=i+1;
		   A[1][i]=1;
		   DFS(A,M,step+1);
		   A[1][i]=0;//使用过后记为0
		}	
	}
	return;
}


阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhagoodwell

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值