Vj程序设计作业H4

B : 截绳子

题目描述

有 n 段绳子,长短不一。现在要从中截出 k 段长度相同的绳子。当然,一段绳子可以截出来多段绳子。截出来的绳子最长是多少?

输入格式

第一行两个整数 n 和 k (1≤n,k≤105)
接下来 n 行,每行有一个整数 ai​ (1≤ai​≤107),代表每根绳子的长度

输出格式

一个数,代表最长长度。相对误差或绝对误差不超过 10−6

测试样例

样例 1

输入:

4 11
802
743
457
539

输出:

200.5

 解答

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n, k;
    cin >> n >> k;
    double a[n];
    double f = 0;
    double t = 100000000;
    // 输入每段绳子的长度,并找到最短的那一根
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
        f = f + a[i];
        if (a[i] < t)
        {
            t = a[i];
        }
    }
    double d1 = 0, d2 = 0;
    double h = 0;
    // 二分法的起点与终点设置
    d1 = t / k; // 最短时为最短绳子一根就可以得到k根绳子
    d2 = f / k; // 最长时为全部绳子合在一起,剪出k根绳子的长度
    int g1 = 0;
    while (1)
    {

        h = (d1 + d2) / 2;
        int u = 0;
        // 假设截取h长度,计算可以获得多少根绳子
        for (int i = 0; i < n; i++)
        {
            u = a[i] / h;
            g1 = g1 + u;
        }
        // h太大时,g1会小于k
        if (g1 < k)
        {
            d2 = h;
        }
        else if (g1 >= k)
        {
            d1 = h;
        }
        g1 = 0;
        // 判断若分界线处小于1e-6时,输出d1即可
        if ((d2 - d1) <= 1e-6)
        {
            break;
        }
    }
    cout << d1 << endl;
    return 0;
}

C : 复印机

题目描述

有一份原稿,需要复印出 n 份复印件出来。有两台复印机,一台可以每 x 秒复印出一份,另一台可以每 y 秒复印出一份。现在想知道,至少需要多久才能复印完成?
提示:复印件也可以被复印

输入格式

一行三个整数 n,x 和 y (1≤n≤2×108,1≤x,y≤10)

输出格式

一个整数,代表复印 n 份的最短时间

测试样例

样例 1

输入:

4 1 1

输出:

3

样例 2

输入:

5 1 2

输出:

4

解答

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n, x, y;
    cin >> n >> x >> y;
    int sum = min(x, y);
    int d1 = (n - 1) * min(x, y);
    int d2 = (n - 1) / (x + y);
    while (1)
    {
        int s = (d1 + d2) / 2;
        if (s == d2)
        {
            break;
        }
        int f = s / x + s / y;
        if (f < n - 1)
        {
            d2 = s;
        }
        else if (f >= n - 1)
        {
            d1 = s;
        }
    }
    cout << d1 + sum << endl;
    return 0;
}

D : 商店

题目描述

一条街上有 n 个商店,在第 i 个商店,可以以 ai​ 的价格买入一个商品,也可以以 ai​ 的价格卖出一个商品。商品很沉,最多只能同时拿着 1 个商品在街上走。现在按照给定顺序依次访问所有商店,那么,最大收益是多少?在获得最大收益的前提下,最少交易次数是多少?

输入格式

第一行一个整数 T (1≤T≤5),代表测试用例个数
下面 T 组数据,其中每一组数据都占两行,其中
第一行一个整数 n (1≤n≤105),代表商店个数
下面一行 n 个整数,其中第 i 个数为 ai​ (0≤ai​<2147483648),代表在第 i 个商店可以买入或卖出商品的价格

输出格式

对于每个例子,输出一行两个整数,分别代表最大收益和获得最大收益的前提下最少的交易次数

测试样例

样例 1

输入:

1
5
9 10 7 6 8 

输出:

3 4

解答

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int T;
    cin >> T; // T次循环
    for (int i = 0; i < T; i++)
    {
        int n;
        cin >> n;        // n个商店
        int a[n];        // 每一个商店的价格
        int b[n];        // 判断是否卖出
        long long x = 0; // 价值
        int d = 0;       // 次数
        // 输入每一个商店的价格,并初始化
        for (int j = 0; j < n; j++)
        {
            cin >> a[j];
            b[j] = 0;
        }
        // 寻找每一个卖出点,将其标记
        for (int j = 0; j < n - 1; j++)
        {
            if (a[j] > a[j + 1])
            {
                b[j] = 1;
            }
        }
        b[n - 1] = 1; // 最后一个商店进行标记
        int w = a[0]; // w是买
        for (int j = 0; j < n; j++)
        {
            if (b[j] == 1) // 如果有标记,进行卖出
            {
                long long h = x;
                x = x + a[j] - w; // 利润计算
                if (h != x)
                // 判断是否有利润的改变,如果没有,相当于没有交易(在该商店买了商品,又马上卖掉)
                {
                    d = d + 2;
                }
                if (j == n - 1)
                {
                    break;
                }
                else
                {
                    w = a[j + 1]; // 在这个地点买入
                }
            }
        }
        cout << x << " " << d << endl;
    }
    return 0;
}

E : 游戏

题目描述

Alice 和 Bob 在做游戏。Alice 写下了 n 个不同的数字,又选取了数字 K。Alice 让 Bob 进行一些操作,每次操作如下:

  1. 选取两个整数 x,y ,它们的差值不超过 K ,即 ∣x−y∣<=K
  2. 删除它们中较小的数字

Bob 的任务是,尽可能多的进行这样的操作。当然 Bob 有可能一次操作都做不了。那么,Bob 最多可以进行多少次操作?

输入格式

第一行两个整数 n,K (1≤n≤105,1≤K≤1012)
下面一行 n 个整数,其中第 i 个数为 ai​ (0≤ai​≤1012),代表 Alice 写下的数字

输出格式

输出一个整数,代表 Bob 最多可以进行的操作次数

测试样例

样例 1

输入:

5 1
3 7 4 1 5 

输出:

2

解答

#include <bits/stdc++.h>

using namespace std;

int main()
{
    long long n, K;
    cin >> n >> K;
    long long a[n];
    int sum = 0;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a, a + n);
    if (n == 1)
    {
        cout << sum << endl;
    }
    else
    {
        for (int i = 0; i < n - 1; i++)
        {
            if ((a[i + 1] - a[i]) <= K)
            {
                sum++;
            }
        }
        cout << sum << endl;
    }
    return 0;
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值