1 条题解
-
0
自动搬运
来自洛谷,原作者为

CashCollectFactory
这个家伙不懒,但什么都留下了搬运于
2025-08-24 22:19:01,当前版本为作者最后更新于2023-11-21 13:38:39,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目大意
题目要求将两排砖按照以下条件排列:
- 前排的要严格矮于后排的。
- 每一排的价格从左到右需要是越来越贵(可以相等)。
贪心解法
这题算是很简单的贪心了。首先将两排砖分别按价格排序,价格相同的划到同一个 set。然后都从最低价开始,拿出前排当前最低价的一块砖摆上(多块的话随意摆一块),然后到后排的当前最低价的砖里面找一块刚好能满足要求的(刚好比前排的高 个单位,没有的话就是比这个高的最矮的),一直到摆完就可以了。要是这时候找不到这样的砖(就是最低价的都比前面的矮),那就知道没法摆了(后排的有砖匹配不上前排,前排出现同样的情况也是一样),直接输出
impossible。由于只需要遍历所有砖块一遍就可以解决,所以总时间复杂度是 。
代码时间(
有点抽象)#include <bits/stdc++.h> using namespace std; int n; struct tile { int index; int price; int height; }; int main() { cin >> n; vector<tile> front_row(n), back_row(n); //读数据,然后仅按价格排序 auto read_tile = [&](vector<tile> &tile_row) { for (int i = 0; i < n; i++) { tile_row[i].index = i + 1; cin >> tile_row[i].price; } for (int i = 0; i < n; i++) cin >> tile_row[i].height; sort(tile_row.begin(), tile_row.end(), [&](const tile &a, const tile &b) { return a.price < b.price; }); }; read_tile(back_row); read_tile(front_row); //存储当前价格相同的tile //height -> iter in front/back row multimap<int,vector<tile>::iterator> front_tile_map, back_tile_map; int front_index = 0, back_index = 0; vector<int> front_ret(n),back_ret(n); int front_ret_index = 0, back_ret_index = 0; //插入当前价格的tile到set struct insert_map_arg{ multimap<int,vector<tile>::iterator>& tile_map; vector<tile>& tile_vec; int& vec_index; } front_map_arg{front_tile_map, front_row, front_index}, back_map_arg{back_tile_map, back_row, back_index}; while (1) { auto insert_map=[&](insert_map_arg& arg){ //每次都尝试insert front map和back map两者中空了的那个 if (arg.tile_map.empty()) { int price = arg.tile_vec[arg.vec_index].price; while (arg.vec_index < arg.tile_vec.size() && arg.tile_vec[arg.vec_index].price == price) { arg.tile_map.insert(make_pair(arg.tile_vec[arg.vec_index].height, arg.tile_vec.begin() + arg.vec_index)); ++arg.vec_index; } } }; insert_map(front_map_arg); insert_map(back_map_arg); //用贪心法,从当前价格区间找出最合适的砖, 具体就是刚好和当前tile差一的 if(front_tile_map.size() < back_tile_map.size()){ for(auto t:front_tile_map){ int frontH=t.second->height; auto iter=back_tile_map.lower_bound(frontH + 1); if(iter==back_tile_map.end()){ cout<<"impossible"<<endl; return 0; } front_ret[front_ret_index++]=t.second->index; back_ret[back_ret_index++]=iter->second->index; back_tile_map.erase(iter); } front_tile_map.clear(); } else{ for(auto t:back_tile_map){ int backH=t.second->height; auto iter=front_tile_map.upper_bound(backH-1); if(iter==front_tile_map.begin()){ cout<<"impossible"<<endl; return 0; } iter=prev(iter); front_ret[front_ret_index++]=iter->second->index ; back_ret[back_ret_index++]=t.second->index; front_tile_map.erase(iter); } back_tile_map.clear(); } if(front_ret_index>=n && back_ret_index>=n) break; } //输出答案 for(auto i:back_ret) cout<<i<<" "; cout<<endl; for(auto i:front_ret) cout<<i<<" "; cout<<endl; return 0; }本代码需要使用 C++11 以上版本才可以,只因里面用了“auto”这个新东西~
- 1
信息
- ID
- 5271
- 时间
- 10000ms
- 内存
- 500MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者