《华为机试》——MP3光标位置 及 洗牌

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 《华为机试》——MP3光标位置 及 洗牌

本期,我给大家带来以下两个题目的讲解:

  • 1、《华为机试》——MP3光标位置 (中等)
  • 2、  2017年校招真题——洗牌 (简单)

以上两个题的难度属于我也给大家标注出来了,接下来,我们一起去分析一波这两个题!


1、MP3光标位置

我们先来研究一下第一个题,首先,我们还是先从题干下手进行理解:

题目如下 :👇

 

输入描述:

  • 1 输入歌曲数量
  • 2 输入命令 U或者D

输出描述:

  • 1 输出当前列表
  • 2 输出当前选中歌曲

示例1

输入:
10
UUUU
输出:
7 8 9 10
7

🤜 题意分析 🤛

第一眼看到这个题,可能会觉得这个一定非常复杂,其实不然,大家通过对题干的解读,我们可以发现其实本题的意思很简单。相信大家应该都使用过mp3的或者原来那个按键手机,有了上述的生活常识理解起来就非常简单。就是对其进行分类讨论,然后针对每种不同的情况进行解析即可!!

我们示例给大家分析一波:

  • 初始时:

  • 第一步:

 

  • 第二步:

 

  • 第三步:

 

  • 第四步:

 

结束操作之后,此时我们还是处于当前页,因此此时first为7,所经历过的有 7,8,9,10 位置,因此最终的输出结果即为我们上述演示的这样。

🤜 解题思路 🤛

本题比较简单,通过解析指令,进行移动即可,分两种情况,歌曲数目不大于4和大于4的情况。

🤜 代码展示 🤛

#include <iostream>
#include<string>
using namespace std;
int main() {
    int n;
    string cmd;
    while (cin >> n >> cmd) {
//将n首歌进行编号1:n,其中num代表当前光标所在的歌曲编号,first代表当前页的第一首歌曲的编号
        int num = 1, first = 1;
        if (n <= 4) {
            //歌曲总数<=4
            for (int i = 0; i < cmd.size(); ++i) {
             //解析命令
                if (num == 1 && cmd[i] == 'U')
                    num = n;
                else if (num == n && cmd[i] == 'D')
                    num = 1;
                else if (cmd[i] == 'U')
                    num--;
                else
                    num++;
            }
            for (int i = 1; i <= n; ++i)
                cout << i << " ";
            cout << endl;
            cout << num << endl;
        } else {
                //歌曲总数>4
            for (int i = 0; i < cmd.size(); ++i) {
                //解析命令
                if (first == 1 && num == 1 && cmd[i] == 'U') {
                    first = n - 3; //将first跳入最后一页
                    num = n;
                } else if (first == n - 3 && num == n && cmd[i] == 'D') {
                    first = num = 1;
                } else if (first != 1 && num == first && cmd[i] == 'U') {
                    first--;
                    num--;
                } else if (first != n - 3 && num == first + 3 && cmd[i] == 'D') {
                    first++;
                    num++;
                } else if (cmd[i] == 'U')
                    num--;
                else
                    num++;
            }
            for (int i = first; i <= first + 3; ++i)
                cout << i << " ";
            cout << endl;
            cout << num << endl;
        }
    }
    return 0;
}

2、洗牌

紧接着研究一下第二个题,首先,我们还是先从题干下手进行理解:

题目如下 :👇

示例1

3
3 1
1
2
3
4
5
6
3 2
1
2
3
4
5
6
2 2
1
1
1
1

🤜 题意分析 🤛

本题的意思是第一行输入歌曲数量,第二行输入指令,最后需要显式的输出也为两行,第一行为当前歌曲所在的列表,第二行为光标所指向的歌曲。

  • 初始时:

就开始移动 j 的下标,此时根据相应的公式我们可以得出洗一次牌之后第一个元素所处的位置,最后根据公式即可得出第一次洗完牌之后各元素所处的位置

🤜 解题思路 🤛

  1. 每次读取一个数之后,算出他经过k次洗牌后的位置,只用一个长度为2n数组用来输出
  2. 根据当前数的位置,可以算出经过一次洗牌后的位置
  3. 如果当前数小于等于n(即在左手),则他下次出现的位置是 2*当前位置
  4. 与之对应的当前位置 + n(即在右手)的牌,则他下次出现的位置是 2*当前位置 + 1

🤜 代码展示 🤛

#include <iostream>
#include<vector>
using namespace std;
int main() {
    int n, m, k;
    cin >> n;
    while (n--) {
        cin >> m >> k;
        int num = 2 * m;
        vector<int> arr(num);
        for (int i = 0; i < num; ++i) {
            cin >> arr[i];
        }
        //开始洗牌
        for (int i = 0; i < k; ++i) {
            vector<int>tmp(arr.begin(), arr.end());
            for (int j = 0; j < m; ++j) {
                arr[2 * j] = tmp[j]; //左手的牌排放的位置
                arr[2 * j + 1] = tmp[j + m];//右手的牌排放的位置
            }
        }
        //输出洗牌的顺序
        for (int i = 0; i < num - 1; ++i)
            cout << arr[i] << " ";
        cout << arr[num - 1] << endl; //最后一张牌后面不能有空格
    }
}
// 64 位输出请用 printf("%lld")

到此,本期的题目讲解便到此结束了!!!

相关文章
【Leetcode -441.排列硬币 -448.找到所有数组中消失的数字】
【Leetcode -441.排列硬币 -448.找到所有数组中消失的数字】
40 0
|
算法 索引
【算法挨揍日记】day09——35. 搜索插入位置、69. x 的平方根
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
82 0
|
定位技术
【CCCC】L3-007 天梯地图 (30分),两次Dijkstra+路径打印(数据点2,4错因),90行最短题解
【CCCC】L3-007 天梯地图 (30分),两次Dijkstra+路径打印(数据点2,4错因),90行最短题解
177 0
|
6月前
|
索引
leetcode-448:找到所有数组中消失的数字
leetcode-448:找到所有数组中消失的数字
35 0
|
存储
LeetCode题:88合并两个有序数组,283移动零,448找到所有数组中消失的数字
LeetCode题:88合并两个有序数组,283移动零,448找到所有数组中消失的数字
68 0
|
存储
华为机试HJ64:MP3光标位置
华为机试HJ64:MP3光标位置
ENVI_IDL:如何对影像进行各种方式的上下左右的颠倒或者翻转.
ENVI_IDL:如何对影像进行各种方式的上下左右的颠倒或者翻转.
336 0
|
算法 索引
【基础算法】浅浅刷个小题 # 搜索插入位置 # 各位相加 # 寻找数组的中心下标 #
【基础算法】浅浅刷个小题 # 搜索插入位置 # 各位相加 # 寻找数组的中心下标 #
1-50可复制到word文档外带圈的数生成方法
1-50可复制到word文档外带圈的数生成方法
212 0
【LeetCode】替换空格&&消失的数字&&分割链表&&除自身以外数组的乘积
【LeetCode】替换空格&&消失的数字&&分割链表&&除自身以外数组的乘积
【LeetCode】替换空格&&消失的数字&&分割链表&&除自身以外数组的乘积