标题:数字划分
w星球的长老交给小明一个任务:
1,2,3...16 这16个数字分为两组。
要求:
这两组数字的和相同,
并且,两组数字的平方和也相同,
并且,两组数字的立方和也相同。
请你利用计算机的强大搜索能力解决这个问题。
并提交1所在的那个分组的所有数字。
这些数字要从小到大排列,两个数字间用一个空格分开。
即类似:1 4 5 8 ... 这样的答案。
注意,只提交这一组数字,不要填写任何多余的内容。
----------------------------------------
笨笨有话说:
只要一个组的成员确定了,另一个组的成员也就确定了。枚举一个组的成员就可以了。
凭直觉,两个组的成员数目不会差太多吧。
歪歪有话说:
既然求 1 所在的那个组,那只要枚举剩余的成员就可以了。
貌似都是8个成员的可能性很大啊。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class Main {
//提前将和 、平方和、立方和计算出来
//只需要求出一组的和后,另一组的和就是 总和 减去 他的和
static int he = 0;
static int phe = 0;
static int lhe = 0;
public static void main(String[] args) {
//因为考虑到不一定是一组8个,所以使用list来存放
List<Integer> s= new ArrayList<Integer>();
for(int i=1;i<=16;i++){
he += i;
phe += i*i;
lhe += i*i*i;
s.add(i);
}
//防诈骗
//自己试试所有的组合组数
for(int i=0;i<=16;i++){
g3(new ArrayList<Integer>(),1,i);
}
}
//组合问题,递归模式
//这道题只要求答案,使用循环组合进行测试更加方便。
public static void g3(List<Integer> ss,int index,int n){
if(ss.size()==n){
if(pan(ss)){
System.out.println(ss);
}
return;
}
for(int i=index;i<=16;i++){
//将该数字填入集合
ss.add(i);
g3(ss,i+1,n);
//回溯
ss.remove(ss.size()-1);
}
}
public static boolean pan(List<Integer> ss){
int num1 = 0;
int num2 = 0;
int num3 = 0;
for(int i=0;i<ss.size();i++){
num1 += ss.get(i);
num2 += ss.get(i)*ss.get(i);
num3 += ss.get(i)*ss.get(i)*ss.get(i);
}
//根据提示,思考加法交换律,
//只要求出一个组的所有数字。
//假设,两个组的和相等,平方和相等,立方和相等,那么
// 2+2 = 4 、 2*2 + 2*2 = 8 、 2*2*2 + 2*2*2 = 16
// 4-2 = 2 、8-2*2 = 2*2 、16-2*2*2 = 2*2*2
//加法交换律,
if(num1*2==he&&num2*2==phe&&num3*2==lhe){
return true;
}else{
return false;
}
}
}