Good day to all! September 30 ended accepting applications to the
school programming HeadHunter 2016 . In this article I would like to review the tasks of the correspondence stage. I hope that my article will be useful, given that when solving problems I had to visit more than a dozen sites. I have little experience in programming, so I do not claim that my decision is the only correct one. I will always be glad to hear your criticism!
When solving problems using the Java programming language.
The article was corrected with the help of user comments: one cycle is used in solving the first task, when calculating the factorial of a natural number, the BigInteger type is used instead of long, the second task is corrected.
Task 1
An equality is given, in which the numbers are replaced by letters: rqr + rqq = sqr. Find how many solutions he has if different numbers correspond to different letters (there are no leading zeros in the number).
To solve this problem, you can choose two ways: solve it head-on using three nested
for loops or convert the expression and use only two nested
for loops.
')
Choose a second path. The letters in the expression conditions of the problem are numbers, which means that each of them varies from
0 to
9 . Now we recall the representation of the number in
decimal number system and transform the expression to the following form:
s = 2r + 0.11q . Then the code for solving the problem will look like this:
Old solutionpublic class FirstTask { public static void main(String[] args){ int count = 0; for (int q = 0; q < 10; q++){ for (int r = 1; r < 10; r++){ if ((r != q)){ double s = 2 * r + 0.11 * q; if (s % 1 == 0 && s != 0 && s < 10) count++; } } } System.out.println("count is " + count); } }
The problem statement states that there should not be leading zeros, based on this, the initial values for the variables were chosen. For the variable
s, you must use the
double type to correctly fulfill the condition
s% 1 == 0 . This program considers the following identities:
101 + 100 = 201.0 202 + 200 = 402.0 303 + 300 = 603.0 404 + 400 = 804.0 count is 4
If we consider that
q = 0 , then we have only one cycle:
public class FirstTask { public static void main(String[] args){ int count = 0; for (int r = 1; 2 * r < 10; r++) count++; System.out.println("count is " + count); } }
Task 2
The smallest m such that m! divided by no more than 10 — this is m = 5 (5! = 120). Similarly, the smallest m is such that m! divided by no more than 25 - this is m = 10. In general, the value of the function s (n) is equal to the smallest number m, such that m! no residue divided by n.
We define the function S (M, N) = ∑s (n) for all n ∈ [M, N]. For example, S (6, 10) = 3 + 7 + 4 + 6 + 5 = 25. Find S (2300000, 2400000).
We divide the task into several stages. We need to build a method that calculates the factorial of a natural number (the
factorial method
(BigInteger m) ), calculates the value of
m , satisfies the condition of the problem (the
mod method
(BigInteger n) ) and the method that calculates the value of the function
S (M, N) (the
solve method
(BigInteger n, BigInteger m) ).
Please note that in the problem
statement it is necessary to find the value of the function
S (2300000, 2400000) , the factorial from the arguments of which will be a large number, therefore for all numeric variables we use the
BigInteger type (otherwise the calculations will be incorrect).
We implement the
factorial method
(BigInteger m) using a loop: multiply the current variable
ret by the for loop variable and then assign the result to it until all the iterations of the loop have been completed.
The
mod (BigInteger n) method searches for the smallest
m value that satisfies the problem condition:
factorial (m)% n == 0 . For the selection of such values, use the
for loop. As soon as such
m was found, exit the loop.
The
solve method
(BigInteger n, BigInteger m) calculates the sum of all values obtained using the
mod (BigInteger n) method using a
for loop, the variable of which changes from
n to
m in increments of one.
Old solution using BigInteger public class SecondTask { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BigInteger n = BigInteger.valueOf(Integer.parseInt(br.readLine())); BigInteger m = BigInteger.valueOf(Integer.parseInt(br.readLine())); solve(n,m); } public static BigInteger factorial(BigInteger n) { BigInteger res = BigInteger.ONE; if (n.intValue() == 0 || n.intValue() == 1) return res; else { for (BigInteger i = BigInteger.ONE; i.compareTo(n) <= 0; i = i.add(BigInteger.ONE)) { res = res.multiply(i); } } return res; } public static BigInteger s(BigInteger n) { BigInteger res = BigInteger.ZERO; for (BigInteger m = BigInteger.ZERO; m.compareTo(n) <= 0; m = m.add(BigInteger.ONE)) { System.out.println("m = " + m); if ((factorial(m)).mod(n).equals(BigInteger.ZERO)) { res = m; break; } } return res; } public static BigInteger solve(BigInteger N, BigInteger M){ BigInteger res = BigInteger.ZERO; for (BigInteger i = N; i.compareTo(M) <= 0; i = i.add(BigInteger.ONE)){ BigInteger m = s(i); res = res.add(m); } return res; }
We test the program for an example in the condition of the problem
S (6, 10) :
6 10 25
The result of executing the program for
S (2300000, 2400000) (the
long type was used:
2300000 2400000 6596625
The solution to this problem uses the algorithm in the
comments .
public class SecondTask { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int m = Integer.parseInt(br.readLine()); Date startSolve = new Date(); solve(n, m); Date finishSolve = new Date(); long solveTime = finishSolve.getTime() - startSolve.getTime(); System.out.println("solveTime is " + solveTime + " ms"); } public static int s(int n) { TreeMap<Integer, Integer> treemap = new TreeMap<Integer, Integer>(); int i = 2, count = 1; while (i <= n){ if (n % i == 0){ if (treemap.containsKey(i)){ count++; treemap.put(i, count); } else { count = 1; treemap.put(i, count); } n = n / i; i--; } i++; } int p = treemap.lastKey(), k = treemap.get(treemap.lastKey()), m = 0; if (k > p){ do k--; while(k > p); m = k * p; } else m = k * p; return m; } public static int solve(int n, int m){ int res = 0; for (int i = n; i <= m; i++) res += s(i); System.out.println(res); return res; } }
We test the program for an example in the condition of the problem
S (6, 10) :
6 10 25 solveTime is 0 ms
The result of the program for the
S (2300000, 2400000) :
2300000 2400000 1796256390 solveTime is 130854 ms
Task 3
Consider all possible numbers a b for 1 <a <6 and 1 <b <6:
22 = 4, 23 = 8, 24 = 16, 25 = 32 32 = 9, 33 = 27, 34 = 81, 35 = 243 42 = 16, 43 = 64, 44 = 256, 45 = 1024, 52 = 25, 53 = 125, 54 = 625, 55 = 3125. If we remove the repetition, we get 15 different numbers. How many different numbers a b for 2 <a <135 and 2 <b <136?
To raise a number to a power, we use the
Math.pow (x, y) method (why reinvent the wheel?). However, when using this method, it is necessary that all numeric variables have a
double type.
We solve the problem using two collections:
ArrayList is used to add elements
a b ,
HashSet is used to remove all duplicate elements from the collection.
public class ThirdTask { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("type the interval for a"); double a1 = Long.parseLong(br.readLine()); double a2 = Long.parseLong(br.readLine()); System.out.println("type the interval for b"); double b1 = Long.parseLong(br.readLine()); double b2 = Long.parseLong(br.readLine()); pow(a1, a2, b1, b2); } public static ArrayList<Double> pow(double a1, double a2, double b1, double b2){ ArrayList<Double> arr = new ArrayList<>(); for (double i = a1 + 1; i < a2; i++){ for (double j = b1 + 1; j < b2; j++){ arr.add(Math.pow(i,j)); } } System.out.println("arr size is " + arr.size()); HashSet<Double> list = new HashSet<Double>(arr); System.out.println("now arr size is " + list.size()); return arr; } }
We test the program for
1 <a <6 and
1 <b <6 :
type the interval for a 1 6 type the interval for b 1 6 arr size is 16 now arr size is 15
The result of the program for
2 <a <135 and
2 <b <136 :
type the interval for a 2 135 type the interval for b 2 136 arr size is 17556 now arr size is 16640
The article turned out to be quite large, and there are still two voluminous tasks ahead of which we need to analyze the logic of sorting the elements. The remaining tasks will be analyzed in the following publication.