列表

详情


NC20024. [HNOI2002]彩票

描述

某地发行一套彩票。彩票上写有1到M这M个自然数。彩民可以在这M个数中任意选取N个不同的数打圈。每个彩民只能买一张彩票,不同的彩民的彩票上的选择不同。
每次抽奖将抽出两个自然数X和Y。如果某人拿到的彩票上,所选N个自然数的倒数和,恰好等于X/Y,则他将获得一个纪念品。
已知抽奖结果X和Y。现在的问题是,必须准备多少纪念品,才能保证支付所有获奖者的奖品。

输入描述

输入文件有且仅有一行,就是用空格分开的四个整数N,M,X,Y。
1 ≤ X, Y ≤ 100,1 ≤ N ≤ 10,1 ≤ M ≤ 50。输入数据保证输出结果不超过10^5。

输出描述

输出文件有且仅有一行,即所需准备的纪念品数量。

示例1

输入:

2 4 3 4

输出:

1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 415ms, 内存消耗: 444K, 提交时间: 2022-10-17 02:08:39

#include <iostream>
using namespace std;
int n, m, x, y;
int ans = 0;
double sum[105];
double obj;
const double eps = 1e-12;

void dfs(double x, int cur = 1, int f = 0) {
    if (f == n) {
        if (x >= -eps && x <= eps) {
            ans++;
        }
        return;
    }
    if (cur > m) return;
    if (x - eps > sum[min(cur + n - f - 1, m)] - sum[cur - 1]) return;
    if (x + eps < sum[m] - sum[m - (n - f)]) return;
    dfs(x, cur + 1, f);
    if (x + eps >= 1.0 / cur) {
        dfs(x - 1.0 / cur, cur + 1, f + 1);
    }
}

int main() {
    cin >> n >> m >> x >> y;
    for (int i = 1; i <= m; i++) sum[i] = sum[i - 1] + 1.0 / i;
    dfs((double) x / y);
    cout << ans << endl;
    return 0;
}

上一题