某笔试题

就是昨天耗子说今日头条题有点难,今天说第三题不会。我说这个不是数据结构模拟题嘛。又不用动脑子,拼码力的题,有时间做不出来活该~

于是敲了个板,至于能不能AC,有没有Bug我也就不知道。毕竟我没有提交过~有什么bug我也管不了,毕竟懒,不上博客。



3

时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB

题目描述:

产品经理(PM)有很多好的idea,而这些idea需要程序员实现。现在有NPM,在某个时间会想出一个 idea,每个 idea 有提出时间、所需时间和优先等级。对于一个PM来说,最想实现的idea首先考虑优先等级高的,相同的情况下优先所需时间最小的,还相同的情况下选择最早想出的,没有 PM会在同一时刻提出两个 idea

同时有M个程序员,每个程序员空闲的时候就会查看每个PM尚未执行并且最想完成的一个idea,然后从中挑选出所需时间最小的一个idea独立实现,如果所需时间相同则选择PM序号最小的。直到完成了idea才会重复上述操作。如果有多个同时处于空闲状态的程序员,那么他们会依次进行查看idea的操作。

求每个idea实现的时间。

输入

输入第一行三个数NMP,分别表示有NPMM个程序员,Pidea。随后有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 <queue>

#include <vector>

#include <iostream>


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<IDEA> totalIdeas;

int validIndex;


int engineerInfo[maxn];

priority_queue<IDEA> pmInfo[maxn];


/***

 * 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;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值