Sicily 1945. Monkeys & Bananas

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;
}                                 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值