问题描述:
凑平方数
把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。 比如:0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...
注意,0可以作为独立的数字,但不能作为多位数字的开始。 分组时,必须用完所有的数字,不能重复,不能遗漏。
如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?
解题思路:先将在1e+10范围内的各位数字不重复的平方数保存在一个字符串数组中(这其中涉及到字符串和数字之前的转换),接着使用深搜将保存下来的每个平方数(字符串)进行拼接,最后若拼接字符串的长度大于10或拼接字符串中的各位数字字符有重复,则返回上一步;如果拼接字符串的长度等于10且各位数字不相同,则将sum++;否则继续连接下一个平方数字符串
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
string pfnum[10000];
int index=0;//保存所有在给定范围内的平方数的个数
int sum=0;
string res[1000000];//记录选出的符合要求的组合
int resindex=0;//记录上一个字符数组的大小
string Zhuan(long long pf){//将长整型转换为字符串
string s;
if(pf==0){
s+='0';
}
while(pf){
s+=(pf%10)+'0';//注意这里相当于将数字倒着保存(最高位在右端,个位在最左端)这样保存不会影响结果
pf/=10;
}
//s+='\0';//貌似此处多加一个\0会使得字符串长度加1,相当于结尾有两个\0?
return s;
}
int check(string s){//检查字符串中是否有重复数字
int book[15]={0};
for(int i=0;i<s.length();i++){
int num=s[i]-'0';
book[num]++;
if(book[num]>1)return 0;//有重复数字
}
return 1;
}
void Inif(){
for(long long i=0;i<100010;i++){
long long pf=i*i;
if(check(Zhuan(pf))){//将其转换为字符串后,若各位数字字符不重复
pfnum[index++]=Zhuan(pf);
}
}
}
void Dfs(int start,string s){
int len=s.length();
if(len>10||check(s)==0){//拼接的字符串不符合要求(长度超过10,有重复数字)
return ;
}
else if(len==10&&check(s)==1){
sum++;
for(int i=0;i<resindex;i++){
cout<<res[i]<<" ";
}
cout<<endl;
return ;
}
else{
for(int i=start;i<index;i++){
res[resindex++]=pfnum[i];
Dfs(i+1,s+pfnum[i]);
resindex--;
}
}
}
int main(){
Inif();//找出给定范围内的所有平方数,并将其转换为字符串放在pfnum字符串数组中
Dfs(0,"");
cout<<sum<<endl;
return 0;
}