就是昨天耗子说今日头条题有点难,今天说第三题不会。我说这个不是数据结构模拟题嘛。又不用动脑子,拼码力的题,有时间做不出来活该~
于是敲了个板,至于能不能AC,有没有Bug我也就不知道。毕竟我没有提交过~有什么bug我也管不了,毕竟懒,不上博客。
第3题
时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB
题目描述:
产品经理(PM)有很多好的idea,而这些idea需要程序员实现。现在有N个PM,在某个时间会想出一个 idea,每个 idea 有提出时间、所需时间和优先等级。对于一个PM来说,最想实现的idea首先考虑优先等级高的,相同的情况下优先所需时间最小的,还相同的情况下选择最早想出的,没有 PM会在同一时刻提出两个 idea。
同时有M个程序员,每个程序员空闲的时候就会查看每个PM尚未执行并且最想完成的一个idea,然后从中挑选出所需时间最小的一个idea独立实现,如果所需时间相同则选择PM序号最小的。直到完成了idea才会重复上述操作。如果有多个同时处于空闲状态的程序员,那么他们会依次进行查看idea的操作。
求每个idea实现的时间。
输入
输入第一行三个数N、M、P,分别表示有N个PM,M个程序员,P个idea。随后有P行,每行有4个数字,分别是PM序号、提出时间、优先等级和所需时间。
所有输入数据范围为 [1, 3000]
输出
输出P行,分别表示每个idea实现的时间点。
样例输入
2 2 5
1 1 1 2
1 2 1 1
1 3 2 2
2 1 1 2
2 3 5 5
样例输出
3
4
5
3
9
#include
#include
#include
using namespace std;
const int maxn = 3010;
/***
* name: pmIdea
* description: idea类,重载小于号按照PM最想完成的idea逻辑.这样在优先队列里,top永远是
* 当前pm最想完成的idea..其实可以用优先队列套优先队列,直接获取当前程序员的选择,但是毕竟懒.
***/
typedef struct pmIdea {
int ideaId;
int providedPMNumber;
int providedTime;
int priority;
int duration;
bool operator < (const struct pmIdea other) const {
if (this->priority == other.priority) {
if (this->duration == other.duration) {
return this->providedTime > other.providedTime;
} else {
return this->duration > other.duration;
}
} else {
return this->priority < other.priority;
}
}
}IDEA;
int pmNumber,engineerNumber,ideaNumber;
int currentTime;
int resolveCount;
int result[maxn];
vector
int validIndex;
int engineerInfo[maxn];
priority_queue
/***
* name: cmp
* description: 用来把所有idea按照提出时间从小到大排序用
***/
bool cmp(IDEA a,IDEA b) {
return a.providedTime < b.providedTime;
}
/***
* name: init
* description: 初始化数据
***/
void init() {
currentTime = 0;
validIndex = 0;
resolveCount = 0;
totalIdeas.clear();
memset(engineerInfo, 0, sizeof(engineerInfo));
memset(result, 0, sizeof(result));
for (int i = 0 ; i < maxn ; i++) {
while (!pmInfo[i].empty()) {
pmInfo[i].pop();
}
}
}
/***
* name: input
* description: 输入当前case数据并将idea按照提出时间排序(越早提出越前)
***/
void input() {
for (int i = 0 ; i < ideaNumber ; i++) {
IDEA newIdea;
newIdea.ideaId = i;
scanf("%d%d%d%d",&newIdea.providedPMNumber
,&newIdea.providedTime
,&newIdea.priority
,&newIdea.duration);
newIdea.providedPMNumber -= 1;
totalIdeas.push_back(newIdea);
}
sort(totalIdeas.begin(), totalIdeas.end(), cmp);
}
/***
* name: isAllEngineerFree
* description: 当前是否所有程序员手里都没有活儿
***/
bool isAllEngineerFree() {
for (int i = 0 ; i < engineerNumber ; i++) {
if (engineerInfo[i] != 0) {
return false;
}
}
return true;
}
/***
* name: isEngineerFree
* description: 当前序号为engineerNumber程序员手里是否有活儿
***/
bool isEngineerFree(int engineerNumber) {
return engineerInfo[engineerNumber] == 0;
}
/***
* name: latestIdeaTime
* description: 最近的提出的下一个Idea的提出时间
***/
int latestIdeaTime() {
return totalIdeas[validIndex].providedTime;
}
/***
* name: latestEngineerFreeTime
* description: 出现下一个程序员有空时,需要流逝的时间
***/
int latestEngineerFreeTime() {
int timeOffset = 0xfffffff;
for (int i = 0 ; i < engineerNumber ; i++) {
if (timeOffset > engineerInfo[i]) {
timeOffset = engineerInfo[i];
}
}
return timeOffset;
}
/***
* name: updateIdeas
* description: 将当前时间以前提出的Idea加入到PMInfo中
***/
void updateIdeas() {
for (int i = validIndex ; i < ideaNumber ; i++) {
if (totalIdeas[i].providedTime <= currentTime) {
validIndex ++;
IDEA thisIdea = totalIdeas[i];
pmInfo[thisIdea.providedPMNumber].push(thisIdea);
} else {
break;
}
}
}
/***
* name: updateEngineerInfo
* description: 更新Engineer的手里的工作情况
***/
void updateEngineerInfo(int timeOffset) {
for (int i = 0 ; i < engineerNumber ; i++) {
engineerInfo[i] = max(engineerInfo[i] - timeOffset, 0);
}
}
/***
* name: updateEngineer
* description: 当前程序员按照提姆选择选择Idea进行工作
***/
void updateEngineer() {
for (int i = 0 ; i < engineerNumber ; i++) {
if (isEngineerFree(i)) {
/// 当前程序员会选择所有PM最想实现的Idea中耗时(duration)最短的.
/// 耗时相同,选择PM序号(providedPMNumber)最小的.
int selectPMNumber = -1;
for (int j = 0 ; j < pmNumber ; j++) {
if (!pmInfo[j].empty()) {
if (selectPMNumber == -1) {
selectPMNumber = j;
continue;
}
IDEA pmJBestIdea = pmInfo[j].top();
IDEA currentBestIdea = pmInfo[selectPMNumber].top();
if (pmJBestIdea.duration == currentBestIdea.duration) {
if (pmJBestIdea.providedPMNumber < currentBestIdea.providedPMNumber) {
selectPMNumber = j;
}
} else if (pmJBestIdea.duration < currentBestIdea.duration) {
selectPMNumber = j;
}
}
}
/// 当前程序员会选择做这个任务,将其pop掉并更新对应信息.
if (!pmInfo[selectPMNumber].empty()) {
IDEA selectedIdea = pmInfo[selectPMNumber].top();
pmInfo[selectPMNumber].pop();
engineerInfo[i] = selectedIdea.duration;
resolveCount ++;
result[selectedIdea.ideaId] = currentTime + selectedIdea.duration;
}
}
}
}
/***
* name: deal
* description: 处理轮询,没有idea轮询到下一个idea到来; 有idea轮询到下一个程序员有空
***/
void deal() {
while (resolveCount < ideaNumber) {
if (isAllEngineerFree()) {
currentTime = latestIdeaTime();
} else {
int timeOffset = latestEngineerFreeTime();
currentTime += timeOffset;
updateEngineerInfo(timeOffset);
}
updateIdeas();
updateEngineer();
}
}
void output() {
for (int i = 0 ; i < ideaNumber ; i++) {
printf("%d\n",result[i]);
}
}
int main() {
while (scanf("%d%d%d",&pmNumber,&engineerNumber,&ideaNumber) == 3) {
init();
input();
deal();
output();
}
return 0;
}