题目
商店里有N件唯一性商品,每件商品有一个价格,第件商品的价格是叫。一个购买方案可以是从N件商品中选择任意件进行购买(至少一件),花费即价格之和。现在你需要求出所有购买方案中花费前K小的方案,输出这些方案的花费。
当两个方案选择的商品集合内至少有一件不同,视为不同方案,因此可能存在两个方案花费相同。
自定义链表 排序 & 存放路径 & 路径去重
static class NodeList {
Node head;
int size = 0;
class Node {
int val;
String load;
Node next;
public Node() {}
public Node(int val, String load) {
this.val = val;
this.load = load;
}
}
public NodeList(){
head = new Node();
}
public void add(int val, String load) {
Node p = head.next;
Node r = new Node(val, load);
if (p == null) {
head.next = r;
size = 1;
return;
}
// 重置路径,不合法不给予添加
String[] split = load.split("->");
int[] arr = new int[split.length];
for (int i = 0; i < split.length; ++i) {
arr[i] = Integer.parseInt(split[i]);
}
Arrays.sort(arr);
for (int i = 0; i < split.length-1; ++i) {
if (arr[i] == arr[i+1]) return;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < arr.length; ++i) {
sb.append(arr[i]);
if(i <arr.length-1) sb.append("->");
}
r.load = sb.toString();
if (!set.contains(r.load)) {
set.add(r.load);
} else {
return;
}
size++;
while (p != null) {
int tempVal = p.val;
String tempLoad = p.load;
if (p.val > val) {
p.val = r.val;
p.load = r.load;
r.val = tempVal;
r.load = tempLoad;
Node nextNode = p.next;
p.next = r;
r.next = nextNode;
return;
} else {
if (p.next == null || p.next.val > val) {
Node t = p.next;
p.next = r;
r.next = t;
return;
}
}
p = p.next;
}
}
public void remove(int val){
Node p = head.next;
Node pre = head;
while (p != null) {
if (p.val == val) {
pre.next = p.next;
size--;
p = pre.next;
} else {
pre = pre.next;
p = p.next;
}
}
}
public int size(){
return size;
}
public void printf() {
Node p = head.next;
System.out.printf("[ ");
while (p != null) {
System.out.printf("%d(%s), ", p.val, p.load);
p = p.next;
}
System.out.printf("]");
}
}
主函数
static HashSet<String> set = new HashSet<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
NodeList nodeList = new NodeList();
int i = 0, count;
while (i < n) {
int val = sc.nextInt();
nodeList.add(val, i+"");
i++;
}
while (k > 0) {
NodeList.Node p = nodeList.head.next;
NodeList.Node t = p;
count = 0;
int min = p.val;
while (t != null) {
if (min == t.val) {
System.out.println(min+" "+t.load);
count++;
k--;
} else {
break;
}
t = t.next;
}
// 组合
int g;
for (NodeList.Node rp = p; rp != null; rp = rp.next) {
if (nodeList.size >= k + count) break;
for (NodeList.Node lp = p.next; lp != null; lp = lp.next) {
if (nodeList.size >= k + count) break;
nodeList.add(rp.val + lp.val, rp.load + "->" +lp.load);
}
}
nodeList.remove(min);
}
}