zoukankan      html  css  js  c++  java
  • 程序设计思维与实践 Week3 作业 (3/4/数据班)

    A - 选数问题

    Given n positive numbers, ZJM can select exactly K of them that sums to S. Now ZJM wonders how many ways to get it!

    Input

    The first line, an integer T<=100, indicates the number of test cases. For each case, there are two lines. The first line, three integers indicate n, K and S. The second line, n integers indicate the positive numbers.

    Output

    For each case, an integer indicate the answer in a independent line.

    Example

    Input
    1
    10 3 10
    1 2 3 4 5 6 7 8 9 10
    
    Output
    4
    

    Note

    Remember that k<=n<=16 and all numbers can be stored in 32-bit integer

    问题分析

    题意是数列中选出K个数,让它们的和等于S。

    01背包问题,每个数都有被选中和没被选中两种状态。使用递归的思路,如果一个数加入已经选好的数之后,总数不超过K,且和仍然小于等于S,这个数就可以被选,然后继续选判断它之后的数。

    为了方便,把选中的数加入一个列表,然后,递归的时候,下次要求的和就应该减去这个数,下次开始的位置是这个数之后相邻的数。

    #include <iostream>
    #include <list>
    using namespace std;
    int tot = 0;
    void selectNumbers(int i, int* arr, int n, int K, int sum, list<int>& res)
    {
        if (res.size() == K && sum == 0)
        {
            tot++;
            return;
        }
        if (i >= n)
            return;
        if (res.size() > K || sum < 0)
            return;
        selectNumbers(i + 1, arr, n, K, sum, res);
        res.push_back(arr[i]);
        selectNumbers(i + 1, arr, n, K, sum - arr[i], res);
        res.pop_back();
    }
    
    int main()
    {
        int* arr = new int[10];
        for (int i = 0; i < 10; ++i)
            arr[i] = 0;
        int T = 0, K = 0, S = 0;
        cin >> T;
        int a = 0, n = 0;
        for (int i = 0; i < T; ++i)
        {
            cin >> n >> K >> S;
            for (int j = 0; j < n; ++j)
                cin >> arr[j];
            tot = 0;
            list<int> res;
            selectNumbers(0, arr, n, K, S, res);
            cout << tot << endl;
        }
        delete[]arr;
        return 0;
    }
    

    B - 区间选点

    数轴上有 n 个闭区间 [a_i, b_i]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)

    Input

    第一行1个整数N(N<=100)

    第2~N+1行,每行两个整数a,b(a,b<=100)

    Output

    一个整数,代表选点的数目

    Examples

    Input
    2
    1 5
    4 6
    
    Output
    1
    
    Input
    3
    1 3
    2 5
    4 6
    
    Output
    2
    

    问题分析

    区间可用结构体表示,存放左右两端点。

    首先把结构按照左端点较大的优先的原则,用sort()排序。这样,如果取排名靠前左端点,则更有可能也在之后的区间内。记下当前区间左端点lastX,如果大于下一个区间的右端点,可以不再取下个区间,继续考虑其后的。

    第一次提交的时候,由于没更新lastX的值,导致出错

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    struct Inteval
    {
        int x, y;
        Inteval() :x(0), y(0) {
    
        }
    }I[105];
    bool cmp(Inteval a, Inteval b)
    {
        if (a.x != b.x)
            return a.x > b.x;
        else
            return a.y < b.y;
    }
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; ++i)
        {
            scanf("%d%d", &I[i].x, &I[i].y);
        }
        sort(I, I + n, cmp);
        int ans = 1, lastX = I[0].x;
        for (int i = 1; i < n; ++i)
        {
            if (I[i].y < lastX) {
                lastX = I[i].x;
                ans++;
            }
                
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    C - 区间覆盖(不支持C++11)

    描述

    数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
    覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
    不可能办到输出-1

    输入

    第一行:N和T
    第二行至N+1行: 每一行一个闭区间。

    输出

    选择的区间的数目,不可能办到输出-1

    样例输入
    3 10
    1 7
    3 6
    6 10
    
    样例输出
    2
    

    提示

    这道题输入数据很多,请用scanf而不是cin

    问题分析

    这道题比较复杂,前面提交了9次都没有过,之后参考了别人写的文章,才得以通过。写完已经有一段时间,原文链接遗失了

    首先看输入,既然输入的区间起点、终点都是整数,那么右端点小于1的和左端点大于t的区间都不可能覆盖[1, t],可以排除在外。对于有部分在[1, t]内的区间,不取外面的那一部分。

    然后考察已经读入的区间,判断是否可以加入,如果可以,更新可覆盖的最大值,最后比较这个值和t

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct Node {
        int l, r;
        bool operator<(const Node& node)const {
            return l < node.l;
        }
    }temp[100010];
    int main() {
        int n, t;
        scanf("%d%d", &n, &t);
        for (int i = 1; i <= n; i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            if (y < 1 || x > t) continue;
            if (x < 1) x = 1;
            if (y > t) y = t;
            temp[i].l = x; temp[i].r = y;
        }
        sort(temp + 1, temp + n + 1);
        if (temp[1].l != 1)
        {
            printf("-1
    ");
            return 0;
        }
        int s = 1;
        int ans = 0;
        int i = 1;
        while (i <= n && s <= t) {
            int Max = -1;
            if (temp[i].l > s) break;
            while (i <= n && temp[i].l <= s) {
                Max = max(Max, temp[i].r);
                i++;
            }
            if (Max != -1) {
                s = Max + 1;
                ans++;
            }
        }
        if (s <= t)
            ans = -1;
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    celery异步任务
    redis过期策略与内存淘汰机制分析
    爬虫数据去重-布隆过滤器
    scrapy-redis数据去重与分布式框架
    redis哨兵机制
    C#从零单排上王者系列---元组
    玩转VSCode插件之Remote-SSH
    C#从零单排上王者系列---数据类型
    Cassandra之Docker环境实践
    centos7安装nginx并配置前端环境
  • 原文地址:https://www.cnblogs.com/master-cn/p/12529856.html
Copyright © 2011-2022 走看看