第七屆藍橋決賽湊平方數

把0~9這10個數字,分成多個組,每個組恰好是一個平方數,這是能夠辦到的。
比如:0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...
注意,0可以作爲獨立的數字,但不能作爲多位數字的開始。
分組時,必須用完所有的數字,不能重複,不能遺漏。
如果不計較小組內數據的先後順序,請問有多少種不同的分組方案?

注意:需要提交的是一個整數,不要填寫多餘內容。

思路:
(1)首先將合格的平方數以字符串的形式存入數組ans 
(2) void dfs(int start,string s); start是ans開始的位置 s是已經選擇的平方數連接構成的字符串
 例如 ans[] = {"0","1","4","9","16","25","36","49",...}
 現在start = 0 ;s = ""; 
 我們選擇了ans[0] = "0" s = "" + "0" = "0"; start = 0+1;
 然後我們選擇ans[1] = "1";s = "0"+"1" = "01"(s是所有的選擇的字符串進行連接);start = 2(表示下一次需要從下標爲2開始選);

 如果某一次 s 的長度爲10 而且沒有重複的字符,那麼sum++; 

注:這是同學給我講完之後我才明白的,所以文章類型選擇翻譯,感謝同學給我講解。

#include<iostream>
#include<string>
using namespace std; 
int total = 0,sum = 0 ;//total是有多少個合格的平方數 sum 是一共多少種組合
string ans[100000];//用來存放合格的平方數的字符串形式 
bool check(string s);//用來檢測s中是否有重複的字符
string toss (long long n);//將數字n轉化爲字符串
void init();//將全部合適的平方數存入數組
void dfs(int start,string s);
int main()
{
	init();
	string s = "";
	dfs(0,s);
	cout<<sum<<endl;
	return 0;
}
void dfs(int start,string s) 
{
	if(s.size()>10 || !check(s)){
		return;
	}
	else if(s.size()==10 && check(s)){
		sum ++;
		return;
	}
	else{
		for(int i=start ;i<total;i++){ 
			dfs(i+1,s+ans[i]);
		}
	}
}
bool check(string s)
{
	int u[10] = {0};
	int i,j;
	for(i=0;i<s.size();i++){
		u[s[i]-'0']++;
		if(u[s[i]-'0']>1){
			return false;
		}
	} 
	return true;
}
string toss (long long n)
{
	string s = "";
	do{
		char c[] = {n%10+'0','\0'};//因爲字符串之間可以連接 c數組相當於一個字符串 
		s = c + s;
		n/=10;
	}while(n!=0);
	return s;	
} 
void init()
{
	long long i,j;
	string s;
	for(i=0;i<1e5+10;i++){//如果i是int型的話就會出錯,我也不太清楚爲什麼 
		j = i*i;
		s = toss(j);
		/*---------如果這個平方數沒有重複的數字的話----------- */
		if(check(s)){
			ans[total++] = s;
		}
	}
}

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