华为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; }
经过验证,题目给出的用例可以通过。
但是上述代码无法保证满分,因为无法验证~~~~~
大家可以讨论一下你的思路呢?