华为OD机考题目《打印任务排序》200分题目


在CSDN上看到一道题, 200分的,叫 《打印任务排序》。
截图:


因为我知道 华为OD的机考题都是ACM模式,所以我找了一下其他的帖子(https://www.online1987.com/%e6%89%93%e5%8d%b0%e4%bb%bb%e5%8a%a1%e6%8e%92%e5%ba%8f/),最终梳理出题目的输入输出:



上面的截图中,有一个至关重要的点,就是你要输出的,是当前这些打印任务最终的打印顺序。9,3,5 而言, 9 是第0个打印, 3 是第 2个打印, 5 是 第 1个打印。

同样,如果我们的输入是 1,2,2, 那么  队列头部的任务优先级是1,所以要放到最后去 ,打印顺序是 2 。 然后接下来的两个2,因此,打印顺序是 0  1   。所以你的最终输出是2,0,1 。

题目中给出的输入,虽然是逗号分隔,但是对于c++代码的 cin整型来讲,会自动把逗号干掉,所以没必要接收 字符串,然后再自行split 。
其他语言也可以参考这个思路。

接收输入的代码片段可以写成:
    deque< pair<int,int> > rVec;//pair: 优先级,序号
    int priority, index = 0;
    while (cin>> priority)
    {
        rVec.push_back(std::pair<int, int>(priority, index++));
        if (cin.get() == '\n')
        {
            break;
        }
    }
说明,因为我要从最开头拿一个出来,判断优先级是不是最高,如果不是,则放到最末尾,所以我用双向队列最好了。当然,其他数据结构也可以。
队列里面之所以用 pair存两个元素,是因为我要记录它的优先级之外,还要记录它的序号,不然一旦从开头拿走一个放到末尾,我就不记得它的序号了,那么就没办法做输出了。

输出的时候,注意最后没有空格,有一个换行。我是这样写的:
    while (!result.empty()) 
    {
        char opr = ',';
        if (result.size() == 1)
        {
            opr = '\n';
        }
        cout << result.front() << opr;
        result.erase(result.begin());
    }
其中 result是一个 vector,里面按顺序存储了每一个任务对应的打印顺序,这段代码主要想说明的是 逗号分隔,最后没有逗号,要有一个换行。

中间的思路是:

我先构造一个result的容器,大小是 输入的任务个数 rVec.size(), 初始化所有值为 0 。
    vector< int> result(rVec.size(),0);

然后,取出deque中的开头那个,起个名字叫 top, 然后跟剩下的所有做优先级对比,如果开头这个优先级不是最高的,那么就把它 pop 出来,塞到最后面去。
如果它的优先级是最高的,则把result的第top.second 个的优先级,按顺序设置,所以要记录一个 index,从0开始。

关键代码:
    index = 0;
    while (!rVec.empty()) 
    {
        //将front 弄成优先级最高的那个,只要front这个不是,就弄到最低下去
        bool isFrontTheMostPriority = true;
        std::pair<int, int> top = rVec.front();
        for (int i = 1; i < rVec.size(); i++) 
        {
            if (rVec[i].first > top.first)
            {
                rVec.push_back(top);
                rVec.pop_front();
                isFrontTheMostPriority = false;
                break;
            }
        }
                // 如果搞了半天,top不是最高优先级,则不要放到result里去,继续上面那个循环。
        if (isFrontTheMostPriority)
        {
            result[top.second] = index;
            rVec.pop_front();
            index++;
        }
    }

把所有代码合并到一起:

int main()
{
    deque< pair<int,int> > rVec;//pair: 优先级,序号
    int priority, index = 0;
    while (cin>> priority)
    {
        rVec.push_back(std::pair<int, int>(priority, index++));
        if (cin.get() == '\n')
        {
            break;
        }
    }

    vector< int> result(rVec.size(),0);
    index = 0;
    while (!rVec.empty()) 
    {
        //将front 弄成优先级最高的那个,只要front这个不是,就弄到最低下去
        bool isFrontTheMostPriority = true;
        std::pair<int, int> top = rVec.front();
        for (int i = 1; i < rVec.size(); i++) 
        {
            if (rVec[i].first > top.first)
            {
                rVec.push_back(top);
                rVec.pop_front();
                isFrontTheMostPriority = false;
                break;
            }
        }

        if (isFrontTheMostPriority)
        {
            result[top.second] = index;
            rVec.pop_front();
            index++;
        }
    }

    while (!result.empty()) 
    {
        char opr = ',';
        if (result.size() == 1)
        {
            opr = '\n';
        }
        cout << result.front() << opr;
        result.erase(result.begin());
    }

    return 0;

}


经过验证,题目给出的用例可以通过。
但是上述代码无法保证满分,因为无法验证~~~~~

大家可以讨论一下你的思路呢?












全部评论
我的思路是把输入处理成列表,然后倒序排序,用字典把它的下标和对应的值存起来,即key-value 对,然后遍历原始列表和字典,原始列表的元素与字典的value 对应上即是它的打印顺序,遍历过的字典打个标记,遍历完成后输出的顺序就是它的实际打印顺序
3 回复 分享
发布于 2022-06-01 17:40
终于有一题不看答案能做出来的🤣
2 回复 分享
发布于 2022-06-05 11:55
回复牛友没得发截图,再评论一次我附上我自己的做题思路
1 回复 分享
发布于 2022-07-01 00:41
没看懂上面的,我这个感觉比较好懂,同时操作value列表和index列表,9,3,5,3是0,2,3,1,值相同前面的反而应该后打印 import sys nums=list(map(int,sys.stdin.readline().strip().split(',&(30872)#39;))) index=[int(i) for i in range(len(nums))] print(index) res=[] while len(nums)>0:     temp=nums.pop(0)     if nums:         if temp>=max(nums):             res.append(index.pop(0))         else:             index=index[1:]+index[:1]             nums.append(temp) res.append(index[0]) print(',&(30872)#39;.join(str(i) for i in res))
点赞 回复 分享
发布于 2022-10-15 16:24 江苏
public class Main {     public static void main(String[] args) {         Scanner scanner = new Scanner(System.in);         String s = scanner.nextLine();         String[] a = s.split(",");         Map<Integer, List<Integer>> map = new HashMap<>();         for (int i = 0; i < a.length; i++) {             map.computeIfAbsent(Integer.valueOf(a[i]), key -> new LinkedList<>()).add(i);         }         List<Integer> list = Arrays.asList(a).stream().map(s1 -> Integer.valueOf(s1)).distinct().collect(Collectors.toList());         Collections.sort(list, Collections.reverseOrder());         List<Integer> resultList = new LinkedList<>();         for (Integer e : list) {             resultList.addAll(map.get(e));         }         System.out.println(String.join(",", resultList.stream().map(integer -> integer.toString()).collect(Collectors.toList())));     } }
点赞 回复 分享
发布于 2022-06-29 18:47
python版,原先没有考虑到2个以上重复元素的情况,【if order in result_l】改为 【while order in result_l】
点赞 回复 分享
发布于 2022-06-23 10:07

相关推荐

评论
1
9
分享

创作者周榜

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