project euler 52

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[n];
			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);
		}

	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值