蓝桥杯 16决赛 A2 凑平方数(锁定数据范围)

蓝桥杯 16决赛 A2 凑平方数(锁定数据范围)

凑平方数
把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等…
注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。
如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

==========================

思路:
找出可能出现的平方数
dfs得到组合数
剪枝,组合数是真的大

总结
long l =990000000; ->The literal xxxxxxxxxx of type int is out of range->long l =xxxL就可了
我的第一个想法->嵌套dfs(组合方式+切分方式),问题就是太慢了,要好几分钟,作为一个 经典的错误案例
Double.isNaN(double d) -true非数字(指的是"78a"," 57"可以被解析成数字,“5 7”/" "不可以)

public class Test{
	static ArrayList<String> list =new ArrayList<String>();
	static boolean[] vis =new boolean[10];
	static int ans;
	public static void main(String[] args) {
		//System.out.println(Integer.MAX_VALUE); //2147483647
		long bound =(long)Math.pow(Double.parseDouble("9876543210"), 0.5);
		for(long l =0L ;l <=bound ;l ++) if(!isRe(l *l)) list.add(l *l +"");
		//排列组合
		dfs(0 ,0);
		//输出结果
		System.out.println(ans);
	}
	private static boolean isRe(long l) {
		char[] a =(l +"").toCharArray();
		for(int i =0 ;i <a.length ;i ++) for(int j =i +1 ;j <a.length ;j ++) if(a[i] ==a[j]) return true;
		return false;
	}
	private static void dfs(int index ,int numb) {
		if(numb ==10) {ans ++; return;}
		char[] tmp =null;
		boolean isVis =false;
		for(int i =index ;i <list.size() ;i ++) {
			tmp =list.get(i).toCharArray();
			//串长是否合法
			if(numb +tmp.length >10) continue;
			//数字是否使用
			isVis =false;
			for(int j =0 ;j <tmp.length ;j ++) if(vis[tmp[j] -48]) {isVis =true; break;}
			if(isVis) continue;
			//标记使用数字
			for(int j =0 ;j <tmp.length ;j ++) vis[tmp[j] -48] =true;
			dfs(i +1 ,numb +tmp.length);
			//回溯
			for(int j =0 ;j <tmp.length ;j ++) vis[tmp[j] -48] =false;
		}
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肯尼思布赖恩埃德蒙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值