Editorial for COCI '16 Contest 4 #4 Rekonstruiraj


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Knowing that the numbers in the input have at most five decimal places, we transform them to positive integers by multiplying them with 100\,000. Mirko's unknown numbers (also multiplied with 100\,000) are obviously some of the divisors of the obtained numbers.

How to efficiently find divisors of X? We can do this by iterating over all of its potential divisors d from 2 to \sqrt X and checking whether X and X/d are divisors of X. For each number, we must find the divisors that are "good", in other words, if they belong to the given set of Mirko's numbers. A divisor is "good" if all of its multiples from a given interval are located in the required set, which is possible to check efficiently.

After finding the set of all the "good" divisors, we must choose the minimal subset where the multiples "cover" all given numbers. This is a variant of the problem known as set cover where you need to choose the minimal number of given subsets that cover the entire given set. Set cover is an NP-complete problem, which means that an efficient solution does not exist. Luckily, solutions exist that are correct in "most cases". The task author excuses himself for thinking that a greedy algorithm, one that always chooses the smallest good divisor that covers a yet uncovered number, necessarily produces the minimal final set, but there is an example for which this doesn't hold (as an exercise, find the example). A greedy algorithm is one of the possible heuristics - algorithms that are very successful, but sometimes produce a suboptimal solution. The test data was such that a greedy algorithm or any other reasonable heuristic performs correctly, scoring all of the points.


Comments

There are no comments at the moment.