凑平方数



凑平方数


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


再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...


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


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


注意:需要提交的是一个整数,不要填写多余内容。



/*


凑平方数


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


再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...


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


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


注意:需要提交的是一个整数,不要填写多余内容。








先取得所有小于十位的平方有611个,dfs遍历这些数,同时用到剪枝,因为有很多数都是一开始马上就不满足条件,
所以即使dfs611个数,也能很快得出答案
 */
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class num2s {
static boolean vis[]=null;
static List<BigInteger> digitlist=null;
public static void main(String[] args) {
// TODO Auto-generated method stub
//
int i=0;
digitlist =new ArrayList<>();
while(true){
BigInteger temp=BigInteger.valueOf(i++).pow(2);
if(temp.toString().length()<=10){
if(check(temp.toString())){
digitlist.add(temp);//digitlist里面存了10位以下长所有的所有平方数
}
}
else{
break;
}
}
System.out.println(digitlist.size());
vis=new boolean[digitlist.size()];
for(int i1=0;i1<digitlist.size();i1++){
vis[i1]=false;
}
dfs(10,"",new HashSet<String>());
System.out.println(result.size());
}
public static Set<Set<String>> result=new HashSet<>();
public static void dfs(int len,String x,Set fig){
//len 表示现在还有的长度,x表示现在的字符串,fig是存x字符串的集合
if(len<0){
return;
}
if(len==0){
//System.out.println(11111+"******");
result.add(fig);//把fig这个set集合加进去,每一个完整的fig集合就是一个可以的最终答案
return;
}
for(int i=0;i<digitlist.size();i++){
if(!vis[i]){
vis[i]=true;//标记位已经取过
String temp=digitlist.get(i).toString();//从digit list里面取一个,一个611个
//因为数都是从小到大排列,如果这个数比len的长度大,那么下面的数就都不用看了
if(len<temp.length()){
vis[i]=false;
break;
}
if(check(x+temp)){//如果取出来的一个和之前的一个满足没有重复的元素 
HashSet tempset=new HashSet<>();//新建set集合,
tempset.addAll(fig);//加入原本的fig
tempset.add(temp);//加入新取得的temp,得到一个新的set集合
dfs(len-temp.length(),temp+x,tempset);//递归
}
vis[i]=false;//回溯

}
}
}
public static boolean check(String string){//检查字符串是否有重复元素,如果有就返回false
  //如果没有就返回true
int len=string.length();
Set<Character> set=new HashSet<>();
for(int i=0;i<len;i++){
set.add(string.charAt(i));
}
if(set.size()==len){
return true;
}
else{
return false;
}
}
}








评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值