1945. Monkeys & Bananas
Constraints
Time Limit: 10 secs, Memory Limit: 32 MB
Description
Have you heard of the story of Monkeys distributing Bananas? This problem is a little different. There are N monkeys living on the island, one day they suddenly find lots of bananas, so they decide to take these bananas respectively, but how can they do?
After quarreling for a long time, they make such a rule: They determine C kinds of choices, each choice contains two integers x and y. We assume that initially there are B bunches of bananas, and then each monkey, from elder to younger, randomly selects one choice to own his bananas. If he selects the ith(1<=i<=C) choice, first he takes yi bunches of bananas, after that, he divides the remaining bananas into xi piles that each pile he divided is equally the same. And at last he takes one pile of bananas. So he totally takes yi bunches and one pile of bananas. And every monkey does the same thing. When the last monkey finishes his choice, they find all the bananas are taken nicely that no bananas are left. Well done!
Though I know their plan, I still don’t know which choice the monkeys have chosen, even the amount of monkeys or bananas at the beginning. Now I just want to find the quantities of bananas out, if there are some B0 bunches of bananas which can satisfy any of distributing process, B0 should be considered as a possible answer.
It comes to your job, I will give you a number K, and you should output the Kth smallest possible answer.
Input
The first line of input there is one integer T (T<=100), giving the number of test cases in the input. Each test case starts with two positive integers Nm (Nm<=100) and C(C<=20), representing the maximum number of monkeys and the number of choices they have decided. In the next C lines each line contains two integers xi(2<=xi<=100) and yi(0<=yi<=100), the meaning of which have been described above. Then comes one line contains an integer K (1<=K<=1,000,000), which is the number I request. There is a blank line between any two successive test cases.
Output
For each test case, output one line with an integer B, which is the answer corresponding to my request in the input. If K is bigger than the number of all the answers, just output “-1” instead. Tips: I know that the amount of the bananas at the beginning should not be more than 10^9.
Sample Input
2 2 2 2 4 3 2 3 2 2 2 4 3 2 6
Sample Output
5-1
// Problem#: 1945 // Submission#: 3589482 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University #include <stdio.h> #include <algorithm> using namespace std; const int MAXC = 100; const int MAXN = 1000000 + 1; const int INF = 0x7fffffff; int cs, N, C, K, t; int banana[MAXN]; int monkey[MAXN]; struct A { int x, y, t, s; bool operator < (const A o) const {return s < o.s;} }a[MAXC], b; void heap_down(int j) { int i; for (b = a[j], i = j;;) if (i * 2 + 2 < C && a[i * 2 + 2] < b && a[i * 2 + 2] < a[i * 2 + 1]) a[i] = a[i * 2 + 2], i = i * 2 + 2; else if (i * 2 + 1 < C && a[i * 2 + 1] < b) a[i] = a[i * 2 + 1], i = i * 2 + 1; else break; a[i] = b; } void heap_up(int j) { int i; for (b = a[j], i = j;;) if ((i - 1) / 2 >= 0 && b < a[(i - 1) / 2]) a[i] = a[(i - 1) / 2], i = (i - 1) / 2; else break; a[i] = b; } int main() { int i; scanf("%d", &cs); while (cs--) { scanf("%d%d", &N, &C); t = 0; banana[0] = monkey[0] = 0; for (i = 0; i < C; i++) { scanf("%d%d", &a[i].x, &a[i].y); a[i].t = 0; a[i].s = a[i].y; } sort(a, a + C); scanf("%d", &K); while (a[0].s != INF && t < K) { if (a[0].s != banana[t]) { t++; banana[t] = a[0].s; monkey[t] = monkey[a[0].t] + 1; for (i = 1; i < C; i++) if (a[i].s == INF && banana[t] % (a[i].x - 1) == 0 && monkey[t] < N) { a[i].s = banana[a[i].t = t] / (a[i].x - 1) * a[i].x + a[i].y; heap_up(i); } } else if (monkey[a[0].t] + 1 < monkey[t]) monkey[t] = monkey[a[0].t] + 1; a[0].s = INF; do { a[0].t++; if (banana[a[0].t] % (a[0].x - 1) == 0 && monkey[a[0].t] < N) { a[0].s = banana[a[0].t] / (a[0].x - 1) * a[0].x + a[0].y; break; } } while (a[0].t < t); heap_down(0); } if (t == K) printf("%d\n", banana[t]); else printf("-1\n"); } return 0; }