26/01/13 19:05
pierotofy
Facebook Hacker Cup: facebook.com/…
Qualcuno e' riuscito a risolverlo con un algoritmo veloce? (Deve terminare entro 5 minuti).
Problema:
Input di esempio:
Output:
Input usato per la valutazione (questo dev'essere eseguito in meno di 5 minuti):
Questa e' la mia soluzione (troppo lenta):
Che ne pensate?
Qualcuno e' riuscito a risolverlo con un algoritmo veloce? (Deve terminare entro 5 minuti).
Problema:
After sending smileys, John decided to play with arrays. Did you know that hackers enjoy playing with arrays? John has a zero-based index array, m, which contains n non-negative integers. However, only the first k values of the array are known to him, and he wants to figure out the rest.
John knows the following: for each index i, where k <= i < n, m[ i] is the minimum non-negative integer which is *not* contained in the previous *k* values of m.
For example, if k = 3, n = 4 and the known values of m are [2, 3, 0], he can figure out that m[3] = 1.
John is very busy making the world more open and connected, as such, he doesn't have time to figure out the rest of the array. It is your task to help him.
Given the first k values of m, calculate the nth value of this array. (i.e. m[n - 1]).
Because the values of n and k can be very large, we use a pseudo-random number generator to calculate the first k values of m. Given positive integers a, b, c and r, the known values of m can be calculated as follows:
m[0] = a
m[i ] = (b * m[i - 1] + c) % r, 0 < i < k
Input
The first line contains an integer T (T <= 20), the number of test cases.
This is followed by T test cases, consisting of 2 lines each.
The first line of each test case contains 2 space separated integers, n, k (1 <= k <= 105, k < n <= 109).
The second line of each test case contains 4 space separated integers a, b, c, r (0 <= a, b, c <= 109, 1 <= r <= 109).
Output
For each test case, output a single line containing the case number and the nth element of m.
John knows the following: for each index i, where k <= i < n, m[ i] is the minimum non-negative integer which is *not* contained in the previous *k* values of m.
For example, if k = 3, n = 4 and the known values of m are [2, 3, 0], he can figure out that m[3] = 1.
John is very busy making the world more open and connected, as such, he doesn't have time to figure out the rest of the array. It is your task to help him.
Given the first k values of m, calculate the nth value of this array. (i.e. m[n - 1]).
Because the values of n and k can be very large, we use a pseudo-random number generator to calculate the first k values of m. Given positive integers a, b, c and r, the known values of m can be calculated as follows:
m[0] = a
m[i ] = (b * m[i - 1] + c) % r, 0 < i < k
Input
The first line contains an integer T (T <= 20), the number of test cases.
This is followed by T test cases, consisting of 2 lines each.
The first line of each test case contains 2 space separated integers, n, k (1 <= k <= 105, k < n <= 109).
The second line of each test case contains 4 space separated integers a, b, c, r (0 <= a, b, c <= 109, 1 <= r <= 109).
Output
For each test case, output a single line containing the case number and the nth element of m.
Input di esempio:
5
97 39
34 37 656 97
186 75
68 16 539 186
137 49
48 17 461 137
98 59
6 30 524 98
46 18
7 11 9 46
97 39
34 37 656 97
186 75
68 16 539 186
137 49
48 17 461 137
98 59
6 30 524 98
46 18
7 11 9 46
Output:
Case #1: 8
Case #2: 38
Case #3: 41
Case #4: 40
Case #5: 12
Case #2: 38
Case #3: 41
Case #4: 40
Case #5: 12
Input usato per la valutazione (questo dev'essere eseguito in meno di 5 minuti):
20
131 74
1 9 10 78736
177 73
7 7 5 56401
164 96
76 2 193 164
137 49
48 17 461 137
1000000000 100000
999999999 1 999999999 1000000000
249718282 93729
1 5 6 999917908
640834505 28785
3 9 1 999946125
1000000000 1
12 7 74 12
28 21
6 5 1 85919
59 26
14 19 681 59
186 75
68 16 539 186
232959116 56689
4 9 1 999903057
110 53
7 7 1 64417
97 39
34 37 656 97
714311129 39521
9 5 9 999998192
220 88
1 8 3 58265
78 51
3 5 5 51230
1000000000 100000
99999 1 99999 100000
977365070 59489
8 5 9 999966210
46 18
7 11 9 46
131 74
1 9 10 78736
177 73
7 7 5 56401
164 96
76 2 193 164
137 49
48 17 461 137
1000000000 100000
999999999 1 999999999 1000000000
249718282 93729
1 5 6 999917908
640834505 28785
3 9 1 999946125
1000000000 1
12 7 74 12
28 21
6 5 1 85919
59 26
14 19 681 59
186 75
68 16 539 186
232959116 56689
4 9 1 999903057
110 53
7 7 1 64417
97 39
34 37 656 97
714311129 39521
9 5 9 999998192
220 88
1 8 3 58265
78 51
3 5 5 51230
1000000000 100000
99999 1 99999 100000
977365070 59489
8 5 9 999966210
46 18
7 11 9 46
Questa e' la mia soluzione (troppo lenta):
#!/usr/bin/ruby counter = 0 numElements = 0 file = File.new("find_the_mintxt.txt", "r") while (line = file.gets) counter = counter + 1 if counter == 1 numElements = line.to_i else nkline = line.chomp abcrline = file.gets.chomp m = [] n,k = nkline.split(' ')[0].to_i, nkline.split(' ')[1].to_i a,b,c,r = abcrline.split(' ')[0].to_i, abcrline.split(' ')[1].to_i, abcrline.split(' ')[2].to_i, abcrline.split(' ')[3].to_i dic = {} dic[a] = 1 m[0] = a for i in 1..(k - 1) m[i] = (b * m[i - 1] + c) % r if dic[m[i]] dic[m[i]] += 1 else dic[m[i]] = 1 end end for i in k..(n - 1) c = 0 c += 1 while not dic[c].nil? #<---- LENTO, come si fa ad accelerare? m[i] = c if dic[m[i]] dic[m[i]] += 1 else dic[m[i]] = 1 end dic[m[i - k]] -= 1 dic.delete(m[i - k]) if dic[m[i - k]] == 0 end puts "Case ##{counter - 1}: #{m[n-1]}" end end file.close
Che ne pensate?
Ultima modifica effettuata da pierotofy 26/01/13 19:06
Il mio blog: piero.dev