凑平方数

凑平方数

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

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值