2023 0906 华为机试学习

每天起床第一句 孟晚舟保佑我能过华为机试

1

题目:每日股票价格

给定某只股票连续N天的价格列表stockPrices,其中stockPrices[i]。表示服票某天的价格,请生成一个新列表,对应位置输出为:要想等到股票价格上涨,至少需要等待的天数,如果股票价格不上涨,对应位置输出为0。

解答要求

时间限制:C/C++ 500ms其他语言: 1000ms内存限制: C/C++ 256MB,其他语言:512MB

输入描述

第一行表示第二行元素的个数N;

第二行为用空格隔开的整数,表示每天股票的价格。

其中0<N<=1000000,每天股票价格为正整数

输出描述

输出为用空格分隔的长度为N的列表,对应位置为:要想等到股票价格上涨,至少需要等待的天数

样例输入

5

33 34 14 12 16

样例输出

1 0 2 1 0

解释:

stockPrices =[33,34,14,12,16]

当i=0时,stockPrices[0] =33,下次价格上涨stockPrices[1]=34,此处输出为 1-0=1

单调栈

impl Solution {
    pub fn at_least_waiting_days(stock_prices: Vec<i32>) -> Vec<i32> {
        let mut waiting = vec![0; stock_prices.len()];
        let mut stack = Vec::new();
        stack.reserve(stock_prices.len());
        stack.push(0);

        for i in 1..stock_prices.len() {
            if stack.is_empty() {
                stack.push(i);
            }else if stock_prices[i] == stock_prices[*stack.last().unwrap()]{
                stack.pop();
                stack.push(i);
            }else if stock_prices[i] < stock_prices[*stack.last().unwrap()] {
                stack.push(i);
            }else {
                while !stack.is_empty() && stock_prices[i] > stock_prices[*stack.last().unwrap()] {
                    let prev = stack.pop().unwrap();
                    waiting[prev] = (i - prev) as i32;
                }
            }
        }

        waiting

    }
}

题目:中庸行者

给定一个m*n的整数阵作为地图,短阵数值为地形高度;中庸行者选择地图中的任意一点作为起点,尝试往上、下、左、右四个相邻格子移动;

移动时有如下约束:

  • 中庸行者只能上坡或者下坡,不能走到高度相同的点;
  • 不允许连续上坡或者连续下坡,需要交替进行;
  • 每个位置只能经过一次,不能重复行走;

请给出中庸行者在本地图内,能连续移动的最大次数。

解答要求

时间限制: C/C++500ms,其他语言:1000ms内存限制: C/C++ 256MB,其他语言:512MB

输入描述

一个只包含整数的二维数组:

3 3

4 7 8
8 6 6
2 6 4

第一行两个数字,分别为行数和每行的列数

后续数据为矩阵地图内容

矩阵边长范围:[1,8];

地形高度范围:[0,100000];

输出描述

一个整数,代表中庸行者在本地图内,能连续移动的最大次数。

样例输入

2 2

1 2

4 3

样例输出

3

解释

3->4->1->2

dfs求最大深度,最难的就是visited的位置和对next visited的判断

struct Solution;
/* ------------------------------------- */
use std::collections::HashMap;

fn show_grid(grid: &Vec<Vec<i32>>, cur: usize, visited: &mut Vec<bool>) {
    let m = grid.len();
    let n = grid[0].len();
    let f = |i, j| i * m + j;
    for i in 0..m {
        for j in 0.. n {
            if f(i,j) == cur {
                print!("🟥 ");
            }else if visited[f(i,j)] {
                print!("⬛ ");
            }else {
                print!("⬜ ");
            }
        }
        println!("");
    }
    println!("----------------------------");
    
}
impl Solution {
    pub fn dfs(grid: &Vec<Vec<i32>>, cur: usize, visited: &mut Vec<bool>, should_up: bool) -> i32 {

        let m = grid.len();
        let n = grid[0].len();
        let mut ans = 0;

        if visited[cur] {return 0;}
        visited[cur] = true;

        let f = |i, j| i * m + j;
        let r = |cur| (cur / n, cur % n);
        // if visited[cur] {return 0;}
        let mv = [[0, 1], [1, 0], [0, -1], [-1, 0]];
        let (i, j) = r(cur);

        for k in 0..4 {
            let y = i as i32 + mv[k][0];
            let x = j as i32 + mv[k][1];

            if y < 0 || y >= m as i32 || x < 0 || x >= n as i32 {
                continue;
            }
            let y = y as usize;
            let x = x as usize;
            // 中庸行者只能上坡或者下坡,不能走到高度相同的点;
            if grid[y][x] == grid[i][j] {
                continue;
            }
            // 不允许连续上坡或者连续下坡,需要交替进行;
            if (should_up && grid[y][x] < grid[i][j]) || (!should_up && grid[y][x] > grid[i][j]) {
                continue;
            }
            let next = f(y, x);
            if visited[next] {// 如果next返回0 那么当前的dfs就是返回1了 但是如果当前的四周都是墙壁 就应该返回0 所以必须要判断next
                continue;
            }

            let dfs = Self::dfs(grid, next, visited, !should_up) + 1;
            ans = ans.max(dfs);

        }

        // show_grid(grid, cur, visited);

        visited[cur] = false;
        ans
    }
    pub fn zyxz(grid: &Vec<Vec<i32>>) -> i32 {
        let m = grid.len();
        let n = grid[0].len();
        let mut ans = i32::MIN;
        let f = |i, j| i * m + j;
        let mut visited = vec![false; n * m];

        for i in 0..m {
            for j in 0..n {
                ans = ans.max(Self::dfs(grid, f(i, j), &mut visited, true))
                         .max(Self::dfs(grid, f(i, j), &mut visited, false));
            }
        }

        ans
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test1() {
        let grid = vec![
            vec![1, 2],
            vec![4, 3],
        ];
        assert_eq!(
            Solution::zyxz(&grid), 3
        )
    }
    #[test]
    fn test2() {
        let grid = vec![
            vec![3, 4, 4],
            vec![3, 2, 4],
            vec![3, 5, 1],
        ];
        assert_eq!(
            Solution::zyxz(&grid), 6
        )
    }
}
fn main() {

}

题目:设备配置数据排序

在现代网络通信设备中,设备的配置数据是一个队列集合。当前设备配置数据存在全局唯一序号id标志此身份,还有一个字段决定此条配置数据的位置信息position。通常,position支持如下几种格式:

1、first:队列头,编码格式:idid -1;

2、end:处于队列尾部,编码格式: id-1id;

3、before id1: 表示id应该在数据id1之前,编码格式id id id1;

4、after id1 表示id应该在数据id1之后,编码格式id id1 id

5、无特别排序指令的id数据,编码格式: $id -1-1

当存在多种排序结果均满足上述排序要求的,则按照id第一次出现在扫序指令队列的前后关系排序,以保证唯一顺序;假定你已收到设备配置数据排序指令队列,需要正确计算出符合排序指令要求的数据id序列。

解答要求

时间限制: C/C++1000ms,其他语言:2000ms  内存限制: C/C++ 256MB,其他语言:512MB

输入描述

第一行代表本次的总配置数据数量,不超过100000;

其余行对应每个具体配置数据id和排序要求。id不超过100000;

输出描述

输出按照要求排序好的数据id序列。

若当前排序指令存在问题,无法排序,则输出-1

样例输入

示例一:

5

1 -1 -1

2 -1 2

3 1 3

4 4 -1

5 4 5

示例二:

3

1 -1 -1

2 2 -1

3 -1 -1

样例输出

示例一:

4 1 3 5 2

示例二:

2 1 3

解释

1和3的position为空,且无其他指令约束,则按照输入顺序排序;

拓扑排序即可 一遍秒

struct Solution;
/* ------------------------------------- */
use std::collections::{HashMap, VecDeque};
/*
1  -1  -1   1 无特别排序
2  -1   2   2 在队列尾部
3   1   3   3 在1之后
4   4  -1   4 在队列头
5   4   5   5 在4后

4 1 3 5 2

    4 <- 5

    1 <- 3
                2

 */
pub fn id_sort(id_seqs: Vec<(i32, i32, i32)>) -> Vec<usize> {
    let mut tail = Vec::new();
    let mut head = Vec::new();
    let mut arrive_time = HashMap::new();
    let mut indegree = vec![0; id_seqs.len() + 1];
    let mut adjs = vec![Vec::new(); id_seqs.len() + 1];
    let seqlen = id_seqs.len();

    for (idx, (a, b, c)) in id_seqs.into_iter().enumerate() {
        let id;
        if a == b && c == -1 {
            // 队列头
            id = a as usize;
            indegree[id] = 0;
            head.push(id);
        }else if a == c && b == -1 {
            // 队列尾部
            id = a as usize;
            tail.push(id);
        }else if a == b && a != c && b != c && c != -1 {
            // a == b 在 c之前
            id = a as usize;
            adjs[id].push(c as usize);
            indegree[c as usize] += 1;
        }else if a == c && a != b && c != b && b != -1 {
            // a == c 在b之后
            id = a as usize;
            adjs[b as usize].push(id);
            indegree[id] += 1;
        }else if b == -1 && c == -1 {
            // 无特别排序指令
            id = a as usize;
        }else {unreachable!()}

        arrive_time.insert(id, idx);
    }

    let mut fifo = Vec::new();
    let mut result = Vec::new();

    //找出无特别排序指令 按时间顺序排序
    for id in 1..=seqlen {
        if indegree[id] == 0 && !tail.contains(&id) && !head.contains(&id){
            fifo.push(id);
        }
    }

    // 在无特别排序指令前面插入头指令
    fifo.sort_by_key(|id| *arrive_time.get(id).unwrap());
    let mut tmp = Vec::new();
    tmp.append(&mut head);
    tmp.append(&mut fifo);
    let mut fifo = tmp.into_iter().collect::<VecDeque<usize>>();

    //拓扑排序
    while !fifo.is_empty() {
        let sz = fifo.len();
        let mut stash = Vec::new();

        for _ in 0..sz {
            
            let cur_id =  fifo.pop_front().unwrap();
            result.push(cur_id);
            
            for adj in adjs[cur_id].iter() {
                indegree[*adj] -= 1;
                if indegree[*adj] == 0 && !tail.contains(adj){// 尾指令最后处理
                    stash.push(*adj);
                }
            }
        }

        stash.sort_by_key(|e| *arrive_time.get(e).unwrap());
        for s in stash.into_iter() {
            fifo.push_back(s);
        }
    }

    // 最后插入尾指令
    result.append(&mut tail);
    result
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test1() {
        assert_eq!(
            id_sort(vec![
                (1 ,-1 ,-1),
                (2 ,-1 , 2),
                (3 , 1 , 3),
                (4 , 4 ,-1),
                (5 , 4 , 5),
            ]), vec![4, 1, 3, 5, 2]
        );
    }

    #[test]
    fn test2() {
        assert_eq!(
            id_sort(vec![
                (1,-1, -1),
                (2,2 ,-1),
                (3,-1, -1),
            ]), vec![2, 1, 3]
        )
    }
}
fn main() {

}

全部评论

相关推荐

牛客383479252号:9,2学生暑期实习失利开始投小厂,给这群人整自信了
点赞 评论 收藏
分享
评论
3
15
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务