把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...
注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。
如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?
比如: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;
}
}
}