Project Euler #28: Number spiral diagonals
Question
Answer : 669171001
Hacker Rank Problem
Solution
Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:
What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
It can be verified that the sum of the numbers on the diagonals is 101.20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
Answer : 669171001
Hacker Rank Problem
Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | import java.io.*; import java.util.*; import java.math.BigInteger; public class Solution { private static long modulo = 1000_000_000 + 7; private static BigInteger modInt = new BigInteger(modulo + ""); public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = in.nextInt(); while (t-- > 0) { long N = in.nextLong(); if (1L == N) System.out.println(N); else bar(N); } in.close(); } private static void useBigInteger(long n) { n /= 2; BigInteger k1 = new BigInteger(n + ""); BigInteger k2 = new BigInteger((n+1) + ""); BigInteger k3 = new BigInteger((8) + ""); BigInteger k4 = new BigInteger((2*n+1) + ""); long m = k1.multiply(k2).multiply(k3).multiply(k4).divide(new BigInteger(3 + "")).mod(modInt).intValue(); // System.out.println(m); long q = k1.multiply(k2).multiply(new BigInteger(2 + "")).mod(modInt).intValue(); // System.out.println(q); long c = k1.multiply(new BigInteger(4 + "")).mod(modInt).longValue(); // System.out.println("c=" + c); long d = 1; long big = (m + q + c + d) % modulo; System.out.println(big); } /** * d1 = (2n + 1) ^2 Hence d1 = 4n^2 + 4n + 1 * The numbers along the other * diagonals are simply derived from d1 by subtracting certain values. * d2 = d1 - 2n Hence d2 = 4n^2 + 2n + 1 * d3 = d2 - 2n Hence d3 = 4n^2 + 1 * d4 = d3 - 2n Hence d4 = 4n^2 - 2n + 1 * Now, all that the problem asks us to do is to sum up * the numbers d1, d2, d3, d4 for n = 1, 2, 3, . . . . .. . .. * sum = summation of (16n^2 + 4n + 4) for n = 1, 2, 3, . . . . . * Now sum up remaining things like * 16 * summation of n^2 = 8 * n * (n+1) * (2 * n + 1) / 3 * 4 * summation of n = 2 * (n) * (n+1) * summation of 4 = 4 * n * * @param n * @return */ private static int bar(long n) { // System.out.println(n + "----------------"); n /= 2; //first step: calculate the summation // long sum = (long) (1+8*n*(n+1)*(2*n+1)/3+2*(n)*(n+1)+4*n); // long partA = 8*n*(n+1)*(2*n+1)/3; // long partB = 2*(n)*(n+1); // long partC = 4*n; // long partD = 1; //second step: calculate the remainder long[] numbers = new long[]{n, n + 1, 2 * n + 1}; replaceDividible(numbers); long a = inverseModulo(modulo, 8, numbers); // System.out.println("a=" + a); numbers = new long[]{n, n + 1}; long b = inverseModulo(modulo, 2, numbers); // System.out.println("b=" + b); numbers = new long[]{n}; long c = inverseModulo(modulo, 4, numbers); // System.out.println("c=" + c); long d = 1; // System.out.println("(int) ((a + b + c + d) % modulo)=" + (int) ((a + b + c + d) % modulo)); long raw = (a + b + c + d) % modulo; System.out.println(raw); return 0; } /** * replace the value of the number that is divisible by 3 * @param a */ private static void replaceDividible(long[] a) { for (int i = 0; i < a.length; i++) { if (a[i] % 3 == 0L) { a[i] /= 3; } } } private static int inverseModulo(long modulo, long base, long[] numbers) { base = base % modulo; //reduce to be below integer type for (int i = 0; i < numbers.length; i++) { numbers[i] %= modulo; } for (long i : numbers) { base = (base * i) % modulo; } return (int) base; } } |
Comments
Post a Comment