第七届蓝桥决赛凑平方数

把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;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_39562286/article/details/80028706