NC16618 [NOIP2008]排座椅
题目
题目描述
上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的 对同学上课时会交头接耳。
同学们在教室中坐成了 行 列,坐在第 行第 列的同学的位置是 ,为了方便同学们进出,在教室中设置了 条横向的通道, 条纵向的通道。
于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通道的位置,因为如果一条通道隔开了两个会交头接耳的同学,那么他们就不会交头接耳了。
请你帮忙给小雪编写一个程序,给出最好的通道划分方案。在该方案下,上课时交头接耳的学生对数最少。
输入描述
第一行,有 各用空格隔开的整数,分别是 ()。
接下来 行,每行有 个用空格隔开的整数,第 行的 个整数 ,表示坐在位置 与 的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻)。
输入数据保证最优方案的唯一性。
输出描述
共两行
第一行包含 个整数,,表示第 行和 行之间、第 行和第 行之间、…、第 行和第 行之间要开辟通道,其中 ,每两个整数之间用空格隔开(行尾没有空格)。
第二行包含 个整数,,表示第 列和 列之间、第 列和第 列之间、…、第 列和第 列之间要开辟通道,其中 ,每两个整数之间用空格隔开(行尾没有空格)。
示例1
输入
4 5 1 2 3 4 2 4 3 2 3 3 3 2 5 2 4
输出
2 2 4
题解
知识点:贪心。
显然,行和列的分布是独立的。记录每行(列)的对数,从大到小排序,取前 () 个再按照行列数排序即可。
代码
#include <bits/stdc++.h> using namespace std; pair<int, int> r[1007], c[1007]; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int m, n, k, l, d; cin >> m >> n >> k >> l >> d; for (int i = 1;i < m;i++) r[i].second = i, r[i].first = 0; for (int i = 1;i < n;i++) c[i].second = i, c[i].first = 0; while (d--) { int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; if (x1 == x2) c[min(y1, y2)].first++; else if (y1 == y2) r[min(x1, x2)].first++; } sort(r + 1, r + m, [&](pair<int, int> a, pair<int, int> b) {return a.first > b.first;}); sort(c + 1, c + n, [&](pair<int, int> a, pair<int, int> b) {return a.first > b.first;}); sort(r + 1, r + k + 1, [&](pair<int, int> a, pair<int, int> b) {return a.second < b.second;}); sort(c + 1, c + l + 1, [&](pair<int, int> a, pair<int, int> b) {return a.second < b.second;}); for (int i = 1;i <= k;i++) cout << r[i].second << " "; cout << '\n'; for (int i = 1;i <= l;i++) cout << c[i].second << " "; cout << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16380054.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)