凑平方数

题目描述

题目来源:2016蓝桥杯国赛

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

把 0 ~ 9 这 10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。

比如:

0, 36, 5948721

再比如:

1098524736
1, 25, 6390784
0, 4, 289, 15376
...

注意,0 可以作为独立的数字,但不能作为多位数字的开始。 分组时,必须用完所有的数字,不能重复,不能遗漏。

如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

思路:

1. 先生成 9876543210(因为这个数是0-9这十个数字组成的最大的数)已内的平方数且平方数不能含有相同的数字,用动态数组v保存;

2. 平方数中是否含有相同的数字可以使用二进制“与”运算来判断,不含相同数字的平方数可以用 一个10位的二进制数status来表示;

3. 使用dfs来寻找刚好可以凑够0-9这个十个数字的平方数的组合;

//2016g 凑平方数
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <set>
vector<long long> v; 

void abc(long long x)   //判断n中是否有重复数字 
{
	int status=0;
	if(x==0)	status=1; 
	while(x)
	{
		if((status&(1<<(x%10)))!=0) return ;   //数字有重复 
		status|=(1<<(x%10)); //更新包含数字的状态
		x/=10; 
	}
	v.push_back(status);   //status 保存的是平方数的状态 
}
void create_pingfangshu()   //创建平方数数组v 
{
	long long i,t;
	for(i=0;;i++)
	{
		t=i*i;
		if(t>9876543210)	break;
		abc(t); 
	 } 
}
int ans=0;

void dfs(int x,int y)  //dfs剪枝 ,x表示从第x个合法数字开始取,y表示当前组合的状态 
{
	if(y==(1<<10)-1)   //y==十个一,满足题目要求(即0~9每个使用一次) 
	{
		ans++;return ;
	}
	for(int i=x;i<v.size();i++)
	{
		if((v[i]&y)==0)  //v[i]与已存状态没有共同数字 
		{
			dfs(i+1,v[i]|y);  //当前取的是第i个,下次从i+1开始取; 
		}
	} 
}
int main()
{
	int i;
	create_pingfangshu();
	dfs(0,0);
	cout<<ans<<endl; 
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值