#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <sstream>
#include <cmath>
#include <set>
using namespace std;
int a[]={0,1,2,3,4,5,6,7,8,9};
long long num[10]; //用来保存每一个排列下搜索到的各个平方数。
set<string> se; //用set来去重,因为题目说不考虑小组内的数字顺序,所以还要排序,使不同的顺序变为一种顺序
bool issqrt(long long x)
{
double d=sqrt(x);
return d==(long long)d;
}
void dfs(int k,int n) //k是当前处理到第几位数字,n是当前平方数需要存到num数组中的下标
{
if(k==10)//k等于10时,表示当前排列处理完毕。
{
long long num2[10];//不能直接对num数组进行排序,因为在回溯的时候还需要用到num
copy(num,num+n,num2);
sort(num2,num2+n);//一定要排序
string str="";
for(int i=0;i<n;i++)
{
stringstream ss;
string s="";
ss<<num2[i];
ss>>s;
str+=s+" ";
}
cout<<str<<endl;
se.insert(str);
return ;
}
if(a[k]==0)
{
num[n]=a[k];
dfs(k+1,n+1);
return ;
}
else
{
long long he=0;//用来保存当前的平方数
for(int i=k;i<10;i++)
{
he=he*10+a[i];
if(issqrt(he))
{
num[n]=he;
dfs(i+1,n+1);
//这里不能加return ,因为递归返回时还需要进一步for循环并下处理。
}
}
}
return ;
}
int main()
{
do
{
memset(num,0,sizeof(num));
dfs(0,0);
}while(next_permutation(a,a+10));
cout<<se.size();
return 0;
}
//借鉴了网上的博客,把思路重新说明了一下,后续还会补充
/*
凑平方数
把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...
注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。
如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?
注意:需要提交的是一个整数,不要填写多余内容。
*/