// UVa 107 - The Cat in the Hat import java.math.BigInteger; import java.util.Scanner; public class Main { private static final BigInteger TWO = BigInteger.valueOf(2); private static final int MAX_EXPONENT = 10000; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); BigInteger heightOfTheInitialCat = scanner.nextBigInteger(); BigInteger numberOfWorkerCats = scanner.nextBigInteger(); while (isNotZero(heightOfTheInitialCat) && isNotZero(numberOfWorkerCats)) { CatSums catSums = calculateCatSums(heightOfTheInitialCat, numberOfWorkerCats); System.out.println(catSums.nonWorkingCats + " " + catSums.heights); heightOfTheInitialCat = scanner.nextBigInteger(); numberOfWorkerCats = scanner.nextBigInteger(); } scanner.close(); } private static CatSums calculateCatSums(BigInteger heightOfTheInitialCat, BigInteger numberOfWorkerCats) { if (isOne(heightOfTheInitialCat) && isOne(numberOfWorkerCats)) return CatSums.of(BigInteger.ZERO, BigInteger.ONE); if (isOne(numberOfWorkerCats)) return CatSums.of(BigInteger.valueOf(log(TWO, heightOfTheInitialCat)), heightOfTheInitialCat.multiply(TWO).subtract(BigInteger.ONE)); SolutionPair pair = solve(heightOfTheInitialCat, numberOfWorkerCats); BigInteger n = pair.n; BigInteger nPlus1 = n.add(BigInteger.ONE); int x = pair.x; BigInteger nonWorkingCatsInThisLevel = BigInteger.ONE; BigInteger nonWorkingCatsSum = nonWorkingCatsInThisLevel; BigInteger heightInThisLevel = heightOfTheInitialCat; BigInteger sumOfHeights = heightInThisLevel; for (int i = 1; i <= x; i++) { nonWorkingCatsInThisLevel = nonWorkingCatsInThisLevel.multiply(n); nonWorkingCatsSum = nonWorkingCatsSum.add(nonWorkingCatsInThisLevel); heightInThisLevel = heightInThisLevel.divide(nPlus1); sumOfHeights = sumOfHeights.add(heightInThisLevel.multiply(nonWorkingCatsInThisLevel)); } nonWorkingCatsSum = nonWorkingCatsSum.subtract(numberOfWorkerCats); return CatSums.of(nonWorkingCatsSum, sumOfHeights); } public static SolutionPair solve(BigInteger b, BigInteger a) { int y = log(TWO, b); for (int x = y; x >= 1; x--) { BigInteger nPlus1 = root(b, x); BigInteger n = nPlus1.subtract(BigInteger.ONE); if (n.pow(x).compareTo(a) >= 0 && nPlus1.pow(x).compareTo(b) == 0) { return SolutionPair.of(n, x); } } return SolutionPair.of(b.subtract(BigInteger.ONE), 1); } /** * Finds the n-th root of radicand i.e. finds x such that x^n = radicand */ private static BigInteger root(BigInteger radicand, int n) { BigInteger left = TWO, right = radicand, sol = BigInteger.ONE; while (left.compareTo(right) <= 0) { BigInteger mid = left.add(right).divide(TWO); BigInteger power = mid.pow(n); if (power.compareTo(radicand) == 0) return mid; else if (power.compareTo(radicand) < 0) { sol = mid; left = mid.add(BigInteger.ONE); } else { right = mid.subtract(BigInteger.ONE); } } return sol; } private static int log(BigInteger base, BigInteger x) { if (base.equals(x)) return 1; if (isOne(x)) return 0; if (x.compareTo(base) < 0) return 0; int left = 1, right = MAX_EXPONENT, sol = 1; while (left <= right) { int mid = (left + right) / 2; BigInteger power = base.pow(mid); if (power.compareTo(x) == 0) return mid; else if (power.compareTo(x) < 0) { sol = mid; left = mid + 1; } else { right = mid - 1; } } return sol; } private static boolean isNotZero(BigInteger bigInt) { return BigInteger.ZERO.compareTo(bigInt) != 0; } private static boolean isOne(BigInteger bigInt) { return BigInteger.ONE.compareTo(bigInt) == 0; } public static class SolutionPair { public final BigInteger n; public final int x; private SolutionPair(BigInteger n, int x) { this.n = n; this.x = x; } public static SolutionPair of(BigInteger n, int x) { return new SolutionPair(n, x); } } public static class CatSums { public final BigInteger nonWorkingCats; public final BigInteger heights; private CatSums(BigInteger nonWorkingCats, BigInteger heights) { this.nonWorkingCats = nonWorkingCats; this.heights = heights; } public static CatSums of(BigInteger nonWorkingCats, BigInteger heights) { return new CatSums(nonWorkingCats, heights); } } }
Monday, November 28, 2016
UVa 107 - The Cat in the Hat
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment