Project Euler P105:Special subset sums: testing 特殊的子集和 检验
Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:
- S(B) ≠ S(C); that is, sums of subsets cannot be equal.
- If B contains more elements than C then S(B) > S(C).
For example, {81, 88, 75, 42, 87, 84, 86, 65} is not a special sum set because 65 + 87 + 88 = 75 + 81 + 84, whereas {157, 150, 164, 119, 79, 159, 161, 139, 158} satisfies both rules for all possible subset pair combinations and S(A) = 1286.
Using sets.txt (right click and “Save Link/Target As…”), a 4K text file with one-hundred sets containing seven to twelve elements (the two examples given above are the first two sets in the file), identify all the special sum sets, A1, A2, …, Ak, and find the value of S(A1) + S(A2) + … + S(Ak).
NOTE: This problem is related to Problem 103 and Problem 106.
记S(A)是大小为n的集合A中所有元素的和。若任取A的任意两个非空且不相交的子集B和C都满足下列条件,我们称A是一个特殊的和集:
- S(B) ≠ S(C);也就是说,任意子集的和不相同。
- 如果B中的元素比C多,则S(B) > S(C)。
例如,{81, 88, 75, 42, 87, 84, 86, 65}不是一个特殊和集,因为65 + 87 + 88 = 75 + 81 + 84,而{157, 150, 164, 119, 79, 159, 161, 139, 158}满足上述规则,且相应的S(A) = 1286。
在4K的文本文件sets.txt(右击并选择“目标另存为……”)中包含了一百组包含7至12个元素的集合(文档中的前两个例子就是上述样例),找出其中所有的特殊和集A1、A2、……、Ak,并求S(A1) + S(A2) + … + S(Ak)的值。
解题
直接利用最优特殊子集的算法解题即可
Java
package Level4; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeSet; public class PE0105{ public static void run(){
String filename = "src/Level4/p105_sets.txt";
ArrayList<int[]> sets = readSets(filename);
int sum = 0;
for(int i=0;i<sets.size();i++){
int[] A = sets.get(i);
if(isOptimum(A)){
sum+= sum(A);
}
}
System.out.println(sum);
}
// 73702
// running time=14s966ms
// 验证 是否是最优子集
// 子集 一个集合可能有多个子集,而下面的程序只是看成两个自己的情况,两个子集的并集等于原来集合,照成程序有问题
public static boolean isOptimum(int[] a){
// 所有的子集
ArrayList<ArrayList<Integer>> sets = MakeSubsets(a);
int size = sets.size();
// System.out.println(size);
for(int i=0;i<size;i++){
ArrayList<Integer> set1 = sets.get(i);
for(int j=i+1;j<size;j++){
ArrayList<Integer> set2 = sets.get(j);
if(!isDisjoint(set1,set2)){
int sum1 = sum(set1);
int sum2 = sum(set2);
if(sum1 == sum2)
return false;
if(set1.size() > set2.size() && sum1 <=sum2)
return false;
if(set1.size() < set2.size() && sum1 >= sum2)
return false;
}
}
}
return true;
} // 求集合的和
public static int sum(ArrayList<Integer> set){
int sum = 0;
for (int i=0;i<set.size();i++)
sum+=set.get(i);
return sum;
}
// 求数组的和
public static int sum(int[] set){
int sum = 0;
for (int i=0;i<set.length;i++)
sum+=set[i];
return sum;
}
// 两个子集元素是否相交 true 相交 false 不相交
public static boolean isDisjoint(ArrayList<Integer> set1,ArrayList<Integer> set2){
int size1 = set1.size();
int size2 = set2.size();
ArrayList<Integer> set = new ArrayList<Integer>();
for(int i=0;i<size1;i++){
int element = set1.get(i);
if(set.contains(element))
return true;
else
set.add(element);
}
for(int i=0;i<size2;i++){
int element = set2.get(i);
if(set.contains(element))
return true;
else
set.add(element);
}
set.clear();
return false; } // 求出所有的子集
public static ArrayList<ArrayList<Integer>> MakeSubsets(int a[]){
ArrayList<ArrayList<Integer>> sets = new ArrayList<ArrayList<Integer>>();
for(int i=1;i<= (int) Math.pow(2,a.length);i++){
ArrayList<Integer> set = MakeSubset(a,i);
sets.add(set);
}
return sets; }
// 求出子集
// 利用 和 1 进行与运算 并移位
// 001001 相当于根据 1 所在的位置取 第 2 第 5的位置对应的数
// &000001
//----------
// 1 取出该位置对应的数
// 下面右移一位后
// 000100
// 下面同理了
public static ArrayList<Integer> MakeSubset(int[] a,int m){
ArrayList<Integer> set = new ArrayList<Integer>();
for(int i=0;i<a.length ;i++){
if( m>0 &&(m&1)==1){
set.add(a[i]);
}
m =m>>1;
}
return set;
}
public static int[] strToarr(String line){
String[] strArr = line.split(",");
int[] A = new int[strArr.length];
for(int i=0;i<strArr.length;i++){
A[i] = Integer.parseInt(strArr[i]);
}
return A;
}
public static ArrayList<int[]> readSets(String filename){
BufferedReader bufferedReader = null;
ArrayList<int[]> sets = new ArrayList<int[]>();
try {
bufferedReader = new BufferedReader(new FileReader(filename));
String line ="";
try {
while((line=bufferedReader.readLine())!=null){
int[] A = strToarr(line);
sets.add(A);
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("文件内部没有数据");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("没有发现文件");
}
return sets;
}
public static void main(String[] args){
long t0 = System.currentTimeMillis();
run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms");
}
}
Project Euler P105:Special subset sums: testing 特殊的子集和 检验的更多相关文章
- Project Euler 106:Special subset sums: meta-testing 特殊的子集和:元检验
Special subset sums: meta-testing Let S(A) represent the sum of elements in set A of size n. We shal ...
- Project Euler 103:Special subset sums: optimum 特殊的子集和:最优解
Special subset sums: optimum Let S(A) represent the sum of elements in set A of size n. We shall cal ...
- Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.
In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...
- Python练习题 037:Project Euler 009:毕达哥拉斯三元组之乘积
本题来自 Project Euler 第9题:https://projecteuler.net/problem=9 # Project Euler: Problem 9: Special Pythag ...
- [project euler] program 4
上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...
- 洛谷P1466 集合 Subset Sums
P1466 集合 Subset Sums 162通过 308提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交 讨论 题解 最新讨论 暂时没有讨论 题目描述 对于从1到N (1 ...
- Python练习题 029:Project Euler 001:3和5的倍数
开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...
- Project Euler 9
题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...
- Codeforces348C - Subset Sums
Portal Description 给出长度为\(n(n\leq10^5)\)的序列\(\{a_n\}\)以及\(m(m\leq10^5)\)个下标集合\(\{S_m\}(\sum|S_i|\leq ...
随机推荐
- 【工作总结】LLDB调试技巧 - 篇一
备忘命令 : 命令“l”可以查看程序当前运行的位置 (lldb) l } - (void)rightBarButtonAction { 命令“bt”也能查看程序运行的调用栈 (lldb) bt * t ...
- 自动化TOPSQL优化脚本
'自动化优化’只是个噱头,要能自动化世界就安静了.只是行里非得要这么个名字. 最基本的抓取系统topsql,是通过awr,但是这样有诸多弊端和不灵活,比如数量较少.不能直接看执行计 ...
- 如何设置potplayer播放时总在最前端
1.测试平台:potplayer 64位 2.步骤:在播放器界面上点击右键->选项->基本->最前端方式-选播放视频时在最前端(或是总在最前端) 3.选择:基本->最前端方式- ...
- C#加密解密算法汇总(转)
方法一: //须添加对System.Web的引用 using System.Web.Security; ... /// <summary& ...
- 简单的linux命令笔记
以下命令都是在ubuntu环境下执行 ftp启动 sudo service vsftpd start
- Struts2中的ModelDriven机制及其运用(转)
所谓ModelDriven,意思是直接把实体类当成页面数据的收集对象.比如,有实体类User如下: package cn.com.leadfar.struts2.actions; public cla ...
- Surface Pro 3 扩展坞体验
Surface Pro 3 的确是Microsoft的诚意之作,虽然价格不便宜,但值得入手. 买完Surface Pro 3 后,没事在某网站上闲逛,这货(扩展坞)映入我的眼帘,看完后,心想,这货必须 ...
- boost之thread
1.boost里的thread创建之后会立即启动. 代码示例: #include <iostream> #include <string> #include <vecto ...
- boost之function
boost中function是对函数指针和函数对象的进行封装的模板类. 定义示例:function<int()> func生成一个空的对象,表示函数参数个数为零,返回类型为int. #in ...
- [错误代码:0x80070002]IIS7及以上伪静态报错404
故障现象:DTCMS开启伪静态功能,VS2010预览正常,发布到IIS后报错404.0错误 (WIN7,WIN8,SERVER2008).模块IISWebCore通知MapRequestHandler ...