蓝桥杯:凑算式(全排列)

1、问题描述
在这里插入图片描述
这个算式中A–I代表1–9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。

这个算式一共有多少种解法?

注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。

2、我对这个问题的看法
  在我看来,这个问题考察的是数字1–9的全排列,即遍历所有的情况,统计符合条件情况的个数。
  注意点:从题目所给的例子中可以看出,要考虑两个分数通分后可以整除的情况。

3、全排列算法详解
算法目的:实现a[k]–a[n-1]的全排列

算法原理:递归回溯生成全排列;

 适用于无重复元素的情况;

具体代码:

void f(int k)      //k是起始位置,考虑第k位,前面已经排定; 
{
//k往后的每个数字都可以放在k位; 
	for(int i=k;i<n;i++)
	{
		{int t=a[i];a[i]=a[k];a[k]=t;}
		f(k+1);         //递归; 
		{int t=a[i];a[i]=a[k];a[k=t];}   //回溯; 
	}
}

4、完整解题代码

#include<iostream>
using namespace std;

int a[]={1,2,3,4,5,6,7,8,9};       //把要全排列的值放入数组中; 
int number=0;                      //统计解法个数; 

bool check()        
{
	int x=a[3]*100+a[4]*10+a[5];         //表示DEF; 
	int y=a[6]*100+a[7]*10+a[8];         //表示GHI; 
	if((a[1]*y+a[2]*x)%(y*a[2])==0&&(a[0]+(a[1]*y+a[2]*x)/(y*a[2]))==10)   //条件判断:1、通分能整除;2,总和=10; 
		return true;
	else 
		return false;
} 

/*
通过递归回溯生成全排列,适用于无重复元素的情况;
  考虑第k位,前面已经排定; 
*/ 

void count(int k)
{
	if(k==9)         //表示一种排列已经产生; 
	{    
		if(check())  //检查该种排列所得的解法是否正确; 
			number++;  //若正确,计数因子number加1; 
	} 
	for(int i=k;i<9;i++)        //实现全排列; 
	{
		{int t=a[i];a[i]=a[k];a[k]=t;}
		count(k+1);        //递归;  
		{int t=a[i];a[i]=a[k];a[k]=t;}   //回溯; 
	}
}
int main()
{
	count(0);         //从第一个元素开始; 
	cout<<number; 
	return 0;
}

5、运行结果
本题的答案为:29
在这里插入图片描述

运行环境:DEV c++

至此,整个题目解答完毕!!!

结语:以上就是我对这个问题的理解、解法,可能存在着更好、更简洁的解法代码,希望大家提出来,我们一起讨论,交换看法,共同进步。若上述代码中存在问题,望大家指正,谢谢大家看到结尾。(∩^∩)

奋斗的2351

发布了12 篇原创文章 · 获赞 3 · 访问量 388

猜你喜欢

转载自blog.csdn.net/weixin_45620022/article/details/104985440