藍橋杯:湊算式(全排列)

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; 
			return;    //遞歸出口; 
		} 
	} 
	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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章