溜冰游戏

题目描述
一个游戏大师和N个孩子正在溜冰场玩游戏。 该游戏由K轮组成。 在第i轮比赛中,这个游戏大师宣布:

第i个轮每个小组由Ai个孩子组成!

那些没有被淘汰的孩子尽可能多组成小组。 在同一轮游戏中,一个孩子最多可能属于一个小组。 无法组成小组的孩子将被淘汰, 其他孩子进入下一轮。

最后,在第K轮之后,刚好剩下两个孩子,他们被宣布为获胜者。

现在已知K和A1,A2,A3······,Ak的值。 但是你不知道N的值时多少,你的任务就是在游戏开始之前,计算出满足要求的N的最大值与最小值,如果N不存在,则输出-1.

输入格式
输入包含两行。

第一行包含一个整数K,表示游戏将会进行K轮。

第二行包含用K个用空格分开的整数,从左往右依次表示
A1,A2,A3······,Ak的值。
输出格式
输出有两种情况。

第一种情况,有解,输出两个整数,第一个整数N位的最大值,第二个整数表示的N最小值。

第二种情况,无解,输出-1。

样例输入1:
4
3 4 3 2
样例输出1:
8 6
样例输入2:
5
3 4 100 3 2
样例输出2:
-1
样例输入3:
10
2 2 2 2 2 2 2 2 2 2
样例输出3:
3 2
数据范围与提示

数据范围:

所有输入的数字均为整数
0<k<1e5
1<Ai<1e9
样例输入输出1解释:

例如,如果游戏以6个孩子开始,则按如下方式进行:

在第一轮中,6个孩子组成2组,每组3个孩子,没有人离开游戏。

在第二轮中,6名孩子组成1组,每组4名孩子,2个孩子离开游戏。

在第三轮中,4名孩子组成1组,每组3个孩子,1名孩子离开游戏。

在第四轮中,3个孩子组成1组,每组2个孩子,1个孩子离开游戏。

最后两个孩子被宣布为获胜者。

样例输入输出2解释:

这种情况时无解的。如果在游戏开始时,孩子的数量少于100人,所有人在第三轮结束之后,都离开了。

#include <bits/stdc++.h>
using namespace std;
int a, n[10005], max1 = -1, min1 = 2147483647;
void f(int x, int y) {
    if (y == 1) {
        max1 = max(max1, x + n[1] - 1);//因为n[0]=0,所以直接取最大值
        min1 = min(min1, x);
        return;
    }
    int k;//k就是比x大的最小的n[y-1]的倍数
    if (x % n[y - 1] == 0) {
        k = x;
    } else {
        k = (x / n[y - 1] + 1) * n[y - 1];
    }
    for (int i = k; i < x + n[y]; i += n[y - 1]) {
        f(i, y - 1);//递归找下一个满足要求的x
    }
}
int main() {
    scanf("%d", &a);
    for (int i = 1; i <= a; i++) {
        scanf("%d", &n[i]);
    }
    f(2, a);
    if (max1 == -1 || n[a] > 2) {//当n[a]>2时,2不是n[a]的倍数,所以无解
        printf("-1");
        return 0;
    }
    printf("%d %d", max1, min1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值