OJ刷题——2081.手机短号、2083.简易版最短距离、2088.Box of Bricks

2081.手机短号

题目描述

Problem - 2081

Problem Description:大家都知道,手机号是一个11位长的数字串,同时,作为学生,还可以申请加入校园网,如果加入成功,你将另外拥有一个短号。假设所有的短号都是是 6+手机号的后5位,比如号码为13512345678的手机,对应的短号就是645678。
现在,如果给你一个11位长的手机号码,你能找出对应的短号吗?

Input:输入数据的第一行是一个N(N <= 200),表示有N个数据,接下来的N行每一行为一个11位的手机号码。

Output:输出应包括N行,每行包括一个对应的短号,输出应与输入的顺序一致。

运行代码

#include <iostream>
#include <string>
using namespace std;
int main() {
    int n;
    cin >> n;
    while (n--) {
        string phone;
        cin >> phone;
        string s = "6" + phone.substr(6, 5);
       cout << s << endl;
    }
    return 0;
}

代码思路

  • int n; cin >> n;:首先读取输入的测试用例数量 n
  • 然后通过一个 while 循环来处理每个测试用例。在每次循环中:
    • string phone; cin >> phone;:读取一个 11 位的手机号码字符串。
    • string s = "6" + phone.substr(6, 5);:通过 substr 函数截取手机号码的后 5 位,并在前面添加字符 6 来得到短号字符串 s
    • cout << s << endl;:输出计算得到的短号。

substr 函数

substr函数用于截取字符串的一部分,其常见用法如下:

  • substr(string, start, length):从stringstart位置开始提取长度为length的子字符串。其中,start表示起始位置,length表示要提取的子字符串的长度。如果length未指定或为空,则返回从start位置到字符串末尾的所有字符。如果length为负数,则默认从start位置取到字符串末尾。
  • substr(string, start):从stringstart位置开始提取到字符串末尾的所有字符。
  • substr(string, -length):从字符串末尾开始向前截取length个字符。

2083.简易版最短距离

题目描述

Problem - 2083

Problem Description

寒假的时候,ACBOY要去拜访很多朋友,恰巧他所有朋友的家都处在坐标平面的X轴上。ACBOY可以任意选择一个朋友的家开始访问,但是每次访问后他都必须回到出发点,然后才能去访问下一个朋友。
比如有4个朋友,对应的X轴坐标分别为1, 2, 3, 4。当ACBOY选择坐标为2的点做为出发点时,则他最终需要的时间为 |1-2|+|2-2|+|3-2|+|4-2| = 4。
现在给出N个朋友的坐标,那么ACBOY应该怎么走才会花费时间最少呢?

Input

输入首先是一个正整数M,表示M个测试实例。每个实例的输入有2行,首先是一个正整数N(N <= 500),表示有N个朋友,下一行是N个正整数,表示具体的坐标(所有数据均<=10000).

Output

对于每一个测试实例,请输出访问完所有朋友所花的最少时间,每个实例的输出占一行。

运行代码

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
int FN(const vector<int>& p) {
    int minTime = INT_MAX;
    for (const auto& start : p) {
        int time = 0;
        for (const auto& pos : p) {
            time += abs(pos - start);
        }
        minTime = min(minTime, time);
    }
    return minTime;
}
int main() {
    int m;
    cin >> m;
    while (m--) {
        int n;
        cin >> n;
        vector<int> p(n);
        for (int i = 0; i < n; i++) {
           cin >> p[i];
        }
        int minTime = FN(p);
       cout << minTime << endl;
    }
    return 0;
}

代码思路

  1. 函数FN(const vector<int>& p):输入:一个整数向量p,代表n个点的位置。目标:找到一个点(向量中的一个元素),使得所有点到该点的曼哈顿距离之和最小。实现:遍历向量中的每个点作为“中心点”,计算所有点到该中心点的曼哈顿距离之和,并记录最小的总距离。

  2. 主函数main():首先,读取测试用例的数量m。然后,对于每一个测试用例:读取点的数量n。读取n个整数,存储到向量p中,表示n个点的位置。调用FN(p)函数,计算并获取最小的曼哈顿距离之和。输出该最小距离。

关键逻辑与算法

  • 算法核心:这是一个典型的寻找中位数问题的变形。在曼哈顿距离的计算中,当所有点的分布是对称的时,中位数位置的点将使得总距离最小。因此,对于一维空间上的点集,直接找到这些点的中位数即可得到最小的曼哈顿距离之和。

  • 时间复杂度:由于代码中直接遍历了所有点作为起点计算总距离,时间复杂度为O(n^2),其中n是点的数量。实际上,这个问题可以通过排序后直接找到中位数来优化,将时间复杂度降至O(nlogn)。

2088.Box of Bricks

题目描述

Problem - 2088

Problem Description

Little Bob likes playing with his box of bricks. He puts the bricks one upon another and builds stacks of different height. “Look, I've built a wall!”, he tells his older sister Alice. “Nah, you should make all stacks the same height. Then you would have a real wall.”, she retorts. After a little consideration, Bob sees that she is right. So he sets out to rearrange the bricks, one by one, such that all stacks are the same height afterwards. But since Bob is lazy he wants to do this with the minimum number of bricks moved. Can you help?

Input

The input consists of several data sets. Each set begins with a line containing the number n of stacks Bob has built. The next line contains n numbers, the heights hi of the n stacks. You may assume 1≤n≤50 and 1≤hi≤100.

The total number of bricks will be divisible by the number of stacks. Thus, it is always possible to rearrange the bricks such that all stacks have the same height.

The input is terminated by a set starting with n = 0. This set should not be processed.

Output

For each set, print the minimum number of bricks that have to be moved in order to make all the stacks the same height.
Output a blank line between each set.

运行代码

#include <iostream>
#include <vector>
using namespace std;
void solve(vector<int>& h) {
    int n = h.size();
    int total = 0;
    for (int ht : h) {
        total += ht;
    }
    int tH = total / n;
    int moves = 0;
    for (int ht : h) {
        if (ht > tH) {
            moves += ht - tH;
        }
    }
    cout << moves << endl;
}
int main() {
    vector<int> h;
    int n;
    while (true) {
        cin >> n;
        if (n == 0) {
            break;
        }
        h.clear();
        for (int i = 0; i < n; i++) {
            int ht;
            cin >> ht;
            h.push_back(ht);
        }
       cout << endl;
        solve(h);
    }
    return 0;
}

代码思路

  1. 读取输入:程序通过一个无限循环等待用户输入,直到输入0为止。每次循环开始时,读取一个整数n,表示接下来要输入的柱子数量。若n为0,则结束循环,程序停止接收更多输入并退出。对于每个非零的n,程序读取接下来的n个整数,代表每个柱子的高度。

  2. 计算平均高度:计算所有柱子高度的总和,并除以柱子的数量n,得到每个柱子应该具有的平均高度tH。这里采用了整数除法,意味着最终所有柱子的高度将被调整为一个整数高度,任何小数部分将被舍去。

  3. 计算移动次数:遍历每个柱子的高度,对于高于平均高度tH的柱子,计算其高出的部分,并累加到moves变量中。这表示需要削减的总次数,以使所有柱子高度等于tH

  4. 输出结果:每处理完一组柱子的高度后,程序输出所需的最小削减次数,然后继续等待下一次输入或结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱姌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值