您的位置:首页 > 其它

project euler 52

2015-12-04 21:38 330 查看


Problem
52

Permuted multiples

It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order.

Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits.

重排的倍数

可以看出,125874和它的两倍251748拥有同样的数字,只是排列顺序不同。

有些正整数x满足2x、3x、4x、5x和6x都拥有相同的数字,求其中最小的正整数。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import junit.framework.TestCase;

public class Prj52 extends TestCase {

/**
* It can be seen that the number, 125874, and its double, 251748, contain
* exactly the same digits, but in a different order.
*
* Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x,
* contain the same digits.
*/
public void test() {

List<int[]> choose = new Comb(9, 6).calculateComb();
List<int[]> allCbs = new Combination(6, 0).generateCom();

for (int[] cb : choose) {
int[] arr = new int[6];

for (int j = 0, k = 0; j < cb.length; j++) {
if (cb[j] == 1) {
arr[k++] = j + 1;
}
}

if (arr[0] != 1) {
continue;
}

Set<Integer> allVals = getAllVals(allCbs, arr);

for (int val : allVals) {

if (allVals.contains(val) && allVals.contains(val * 2)
&& allVals.contains(val * 3)
&& allVals.contains(val * 4)
&& allVals.contains(val * 5)
&& allVals.contains(val * 6)) {

System.out.println("val=" + val);
return;
}
}

}
}

private Set<Integer> getAllVals(List<int[]> allCbs, int[] arr) {

Set<Integer> ret = new HashSet<Integer>();

for (int i = 0; i < allCbs.size(); i++) {
int[] val = new int[arr.length];
int[] id = allCbs.get(i);
for (int j = 0; j < arr.length; j++) {
val[j] = arr[id[j]];
}
ret.add((int) Combination.getIntVal(val));
}

return ret;
}

public static class Combination {
private int[] startArr;

public Combination(int size) {

this(size, 1);
}

public Combination(int size, int startNum) {
startArr = new int[size];
for (int i = 0; i < size; i++) {
startArr[i] = i + startNum;
}
}

public List<int[]> generateCom() {
List<int[]> ret = new ArrayList<int[]>();

ret.add(Arrays.copyOf(startArr, startArr.length));

while (true) {

int lastAsc = findLastAsc(startArr);

if (lastAsc == -1) {
break;
}

int lasBigThanAsc = findBigThanAsc(startArr, lastAsc);

exchangeEach(lastAsc, lasBigThanAsc, startArr);

ret.add(Arrays.copyOf(startArr, startArr.length));
}

return ret;
}

private int findBigThanAsc(int[] startArr2, int lastAsc) {
int i = 0;
for (i = startArr2.length - 1; i > lastAsc; i--) {
if (startArr2[i] > startArr2[lastAsc]) {
return i;
}
}

assert (i > lastAsc);
return i;
}

private void exchangeEach(int lastAsc, int lasBigThanAsc,
int[] startArr2) {

int temp = startArr2[lastAsc];
startArr2[lastAsc] = startArr2[lasBigThanAsc];
startArr2[lasBigThanAsc] = temp;

int[] sortArr = getCopyArr(lastAsc + 1, startArr2);

for (int i = 0; i < sortArr.length / 2; i++) {

temp = sortArr[sortArr.length - 1 - i];
sortArr[sortArr.length - 1 - i] = sortArr[i];
sortArr[i] = temp;
}

for (int i = lastAsc + 1; i < startArr2.length; i++) {
startArr2[i] = sortArr[i - lastAsc - 1];
}
}

private int[] getCopyArr(int start, int[] startArr2) {

int[] ret = new int[startArr2.length - start];
for (int i = start; i < startArr2.length; i++) {
ret[i - start] = startArr2[i];
}

return ret;
}

private int findLastAsc(int[] startArr2) {
for (int i = startArr2.length - 1; i > 0; i--) {
if (startArr2[i] > startArr2[i - 1]) {
return i - 1;
}
}
return -1;
}

public static long getIntVal(int[] arr) {
long sum = arr[0];

for (int i = 1; i < arr.length; i++) {
sum = sum * 10 + arr[i];
}

return sum;

}
}

public static class Comb {

private int n;
private int p;

public Comb(int n, int p) {
this.n = n;
this.p = p;
}

public List<int[]> calculateComb() {

assert (p < n && p > 0);

List<int[]> ret = new ArrayList<int[]>();

int[] arrs = new int
;
for (int i = 0; i < p; i++) {
arrs[i] = 1;
}

ret.add(Arrays.copyOf(arrs, arrs.length));

for (;;) {

boolean find = findNext(arrs);
ret.add(Arrays.copyOf(arrs, arrs.length));
if (!find) {
break;
}

}

return ret;

}

private boolean findNext(int[] arrs) {

int count = 0;
int find = -1;

for (int i = 0; i < arrs.length - 1; i++) {
if (arrs[i] == 1) {
count++;
}

if (arrs[i] == 1 && arrs[i + 1] == 0) {

int tmp = arrs[i + 1];
arrs[i + 1] = arrs[i];
arrs[i] = tmp;
find = i;
break;
}

}

count--;

for (int i = 0; i < find; i++) {
if (i < count) {
arrs[i] = 1;
} else {
arrs[i] = 0;
}
}

return !(find == -1);
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: