题目
会议接待
某公司计划在未来几天内举行多场会议,每场会议都有一个开始时间和结束时间。作为会议接待人员,你需要安排会议室的使用,使得在同一时间不会有两场会议同时进行。由于会议室资源有限,你需要确定是否所有会议都能找到合适的会议室进行。
输入
输入包含多行数据,第一行包含两个整数 n 和 m,分别表示会议的数量和会议室的数量。接下来 n 行,每行包含两个整数 start 和 end,表示每个会议的开始时间和结束时间。
输出
如果所有会议都能找到合适的会议室进行,则输出 "YES";否则输出 "NO"。
示例
输入
3 2
1 3
2 4
5 6
输出
YES
解释
前两个会议有重叠时间,但它们可以分别安排在两个会议室中。第三个会议与前两个会议没有重叠时间,因此也可以找到一个会议室进行。
思路
这个问题可以使用贪心算法和线段树或扫描线算法来解决。为了简化实现,我们可以采用一种基于优先队列(最小堆)的方法,这种方法的核心思想是:
- 排序:首先将所有会议按开始时间排序。如果开始时间相同,则按结束时间排序。
- 优先队列:使用一个优先队列(最小堆)来存储当前正在进行的会议的结束时间。
- 遍历会议:遍历每个会议,检查当前会议的开始时间是否早于队列中最小的结束时间:
- 如果是,说明当前会议与至少一个正在进行的会议冲突,没有足够的会议室,输出 "NO"。
- 如果不是,将当前会议的结束时间加入优先队列,并继续遍历。
- 检查完成:如果遍历完所有会议都没有冲突,则输出 "YES"。
Java 语言解析
import java.util.*;
public class MeetingScheduler {
static class Meeting implements Comparable<Meeting> {
int start, end;
Meeting(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public int compareTo(Meeting other) {
if (this.start != other.start) {
return this.start - other.start;
} else {
return this.end - other.end;
}
}
}
public static String canScheduleMeetings(int n, int m, Meeting[] meetings) {
if (m >= n) return "YES"; // 如果会议室足够多,直接可以安排
Arrays.sort(meetings);
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (Meeting meeting : meetings) {
while (!pq.isEmpty() && pq.peek() <= meeting.start) {
pq.poll(); // 移除已经结束的会议
}
if (pq.size() < m) {
pq.offer(meeting.end); // 安排会议并加入队列
} else {
return "NO"; // 没有足够的会议室
}
}
return "YES";
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
Meeting[] meetings = new Meeting[n];
for (int i = 0; i < n; i++) {
int start = scanner.nextInt();
int end = scanner.nextInt();
meetings[i] = new Meeting(start, end);
}
System.out.println(canScheduleMeetings(n, m, meetings));
}
}
C++ 语言解析
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
struct Meeting {
int start, end;
bool operator<(const Meeting& other) const {
if (start != other.start) {
return start < other.start;
} else {
return end < other.end;
}
}
};
string canScheduleMeetings(int n, int m, const vector<Meeting>& meetings) {
if (m >= n) return "YES";
vector<Meeting> sortedMeetings = meetings;
sort(sortedMeetings.begin(), sortedMeetings.end());
priority_queue<int, vector<int>, greater<int>> pq;
for (const auto& meeting : sortedMeetings) {
while (!pq.empty() && pq.top() <= meeting.start) {
pq.pop();
}
if (pq.size() < m) {
pq.push(meeting.end);
} else {
return "NO";
}
}
return "YES";
}
int main() {
int n, m;
cin >> n >> m;
vector<Meeting> meetings(n);
for (int i = 0; i < n; ++i) {
cin >> meetings[i].start >> meetings[i].end;
}
cout << canScheduleMeetings(n, m, meetings) << endl;
return 0;
}
Python 语言解析
import heapq
class Meeting:
def __init__(self, start, end):
self.start = start
self.end = end
def __lt__(self, other):
if self.start != other.start:
return self.start < other.start
else:
return self.end < other.end
def can_schedule_meetings(n, m, meetings):
if m >= n:
return "YES"
meetings.sort()
pq = []
for meeting in meetings:
while pq and pq[0] <= meeting.start:
heapq.heappop(pq)
if len(pq) < m:
heapq.heappush(pq, meeting.end)
else:
return "NO"
return "YES"
if __name__ == "__main__":
n, m = map(int, input().split())
meetings = []
for _ in range(n):
start, end = map(int, input().split())
meetings.append(Meeting(start, end))
print(can_schedule_meetings(n, m, meetings))