凑平方数
把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?
注意:需要提交的是一个整数,不要填写多余内容。
方法一、
找到所有10位数以内的平方数并有序存储,按顺序组合平方数,知道位数为10(当首个数是0时,累加的数位数为9)时,判断是否唯一包含0~9。
#include <iostream>
#include <cstring>
#include <vector>
#include <set>
using namespace std;
#define MAX 10000000000
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
vector<long long> square;
set<int>s;
int flag[10];
int count;
//返回数字位数
int GetNumLen(long long num)
{
int len = 0;
while(num > 0)
{
len++;
num /= 10;
}
return len;
}
//返回10的倍数
int GetTen(int len)
{
int num = 1;
while(len)
{
num *= 10;
len--;
}
return num;
}
//判断是否有重复数字,没有返回1,有返回0
bool is_fit(long long num)
{
memset(flag,0,sizeof(flag));
int temp;
while(num > 0)
{
temp = num%10;
if(flag[temp] == 1)
return 0;
flag[temp] = 1;
num /= 10;
}
return 1;
}
//初始化square数组,十位数范围内的平方数,且每个数都由不同的数组成
void Init()
{
long long num;
for(long long i = 0; i < 100000; i++)
{
num = i*i;
if(num >= MAX)//数字位数超过10位,不再寻找
break;
if(is_fit(num))//平方数满足要求,放入square数组
square.push_back(num);
}
}
//判断数字num 是否唯一包含数字0~9
bool is_ok(long long num)
{
s.clear();
int numlen = GetNumLen(num);
if(numlen == 9)
{
s.insert(0);
}
int temp;
while(num > 0)
{
temp = num%10;
s.insert(temp);
num /= 10;
}
if(s.size() == 10)
return 1;
return 0;
}
void dfs(long long num,int numLen,int pos)
{
if(numLen == 10 && is_ok(num))
{
count++;
}
int size = square.size();
for(int i = pos; i < size; i++)
{
int len = GetNumLen(square[i]);
if(numLen + len > 10)
break;
else
{
if(i == 0)
{
dfs(0,1,1);
}
else
{
int Ten = GetTen(len);
long long t_num = num*Ten+square[i];
int t_numLen = numLen+len;
dfs(t_num, t_numLen, i+1);
}
}
}
}
int main() {
Init();
dfs(0,0,0);
cout<<count<<endl;
return 0;
}
方法二、
#include<iostream>
#include<cstring>
#include<math.h>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
long long shu[20];
int ai[10]={0,1,2,3,4,5,6,7,8,9};
set<string> jj;
void dfs(int cur,int num) //cur为数的位置,num为切的位置
{
if(cur==10)
{
long long shu2[20];
for (int i = 0; i<num; i++)
shu2[i] = shu[i];//将存储的数字赋值
sort(shu2, shu2 + num);//排序
string xu;
for (int i = 0; i<num; i++)
{
while (shu2[i])
{
int a = shu2[i] % 10;
shu2[i] = shu2[i] / 10;
char b = a + '0';
xu = xu + b;
}
xu += '-';
}
for (int i = 0; i < num; i++)
cout << shu[i] << " ";
cout << endl;
jj.insert(xu);
return;
}
if(ai[cur]==0)//如果第表示0 那么直接进行下一个数字
{
shu[num]=0;
dfs(cur+1,num+1);
}
else
{
long long sum=0;
for(int i=cur;i<10;i++)
{
sum=sum*10+ai[i];
double son=sqrt(sum);
if(son==(int)son)
{
shu[num]=sum;
dfs(i+1,num+1);
}
}
}
}
int main()
{
do
{
memset(shu,0,sizeof(shu));
dfs(0,0);
}while(next_permutation(ai,ai+10)); //全排列
cout<<jj.size()<<endl;
return 0;
}