首页 > 试题广场 >

编程题3

[编程题]编程题3
  • 热度指数:2697 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 80M,其他语言160M
  • 算法知识视频讲解

产品经理(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序号、提出时间、优先等级和所需时间。输出P行,分别表示每个idea实现的时间点。


输入描述:
输入第一行三个数N、M、P,分别表示有N个PM,M个程序员,P个idea。随后有P行,每行有4个数字,分别是PM序号、提出时间、优先等级和所需时间。全部数据范围 [1, 3000]。


输出描述:
输出P行,分别表示每个idea实现的时间点。
示例1

输入

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
我觉得今日头条出的题都非常有水平,本人愚见,这题考察了程序设计中最基本的知识“面向对象编程”,和其他考数据结构和算法的题不一样。这里贴一个Java的代码:
import java.util.*;

public class Main {
    public static void main( String[] args ) {
        Scanner sc = new Scanner( System.in );
        int n = sc.nextInt(), m = sc.nextInt(), p = sc.nextInt();
        Idea[] ideas = new Idea[p];
        Thinker[] thinkers = new Thinker[n];
        Implementor[] implementors = new Implementor[m];
        for( int i = 0; i < m; i ++ )
            impleQueue.push( implementors[i] = new Implementor() );
        for( int i = 0; i < n; i ++ )
            thinkers[i] = new Thinker( i );
        for( int i = 0; i < p; i ++ ) {
            int pm = sc.nextInt()-1;
            int time = sc.nextInt();
            int prio = sc.nextInt();
            int cost = sc.nextInt();
            ideas[i] = new Idea( time, prio, cost );
            events.offer( thinkers[pm].getIdea( ideas[i] ) );
        }
        while( !events.isEmpty() ) {
            int time = events.peek().time;
            do { events.poll().occur();
            } while( !events.isEmpty() && events.peek().time == time );
            while( !impleQueue.isEmpty() && !thinkerQueue.isEmpty() ) {
                Thinker tmp1 = thinkerQueue.poll();
                Implementor tmp2 = impleQueue.pop();
                Idea tmp3 = tmp1.ideaQueue.poll();
                tmp3.finish = time + tmp3.cost;
                events.offer( tmp2.peekIdea( tmp3 ) );
                if( !tmp1.ideaQueue.isEmpty() ) thinkerQueue.offer( tmp1 );
            }
        }
        for( int i = 0; i < p; i ++ )
            System.out.println( ideas[i].finish );
        sc.close();
    }
    static PriorityQueue<Thinker> thinkerQueue = new PriorityQueue<>(
        (Thinker t1,Thinker t2) -> {
            int c1 = t1.ideaQueue.peek().cost;
            int c2 = t2.ideaQueue.peek().cost;
            return c1 == c2 ? t1.order - t2.order : c1 - c2;
        }
    );
    static ArrayDeque<Implementor> impleQueue = new ArrayDeque<>();
    static PriorityQueue<Event> events =
        new PriorityQueue<>( (Event e1,Event e2) -> e1.time - e2.time );
    static class Idea {
        int time, prio, cost, finish;
        Idea( int t, int p, int c ) { time = t; prio = p; cost = c; }
    }
    static class Thinker {
        PriorityQueue<Idea> ideaQueue = new PriorityQueue<>(
            (Idea i1,Idea i2) -> {
                if( i1.prio != i2.prio ) return i2.prio - i1.prio;
                else if( i1.cost != i2.cost ) return i1.cost - i2.cost;
                else return i1.time - i2.time;
            }
        );
        int order;
        Thinker( int o ) { order = o; }
        IdeaEvent getIdea( Idea idea ) {
            return new IdeaEvent( this, idea );
        }
    }
    static class Implementor {
        FinishEvent peekIdea( Idea idea ) {
            return new FinishEvent( this, idea );
        }
    }
    static abstract class Event {
        int time;
        Event( int t ) { time = t; }
        abstract void occur();
    }
    static class IdeaEvent extends Event {
        Thinker thinker;
        Idea idea;
        IdeaEvent( Thinker t, Idea i ) {
            super( i.time );
            thinker = t; idea = i;
        }
        void occur() {
            thinkerQueue.remove( thinker );
            thinker.ideaQueue.offer( idea );
            thinkerQueue.offer( thinker );
        }
    }
    static class FinishEvent extends Event {
        Implementor implementor;
        Idea idea;
        FinishEvent( Implementor imple, Idea i ) {
            super( i.finish );
            implementor = imple; idea = i;
        }
        void occur() {
            impleQueue.push( implementor );
        }
    }
}

发表于 2019-01-25 12:52:49 回复(1)
发表于 2018-01-27 21:15:34 回复(1)
思路:暴力枚举时间,按照优先级依次选择Idea

代码如下:
#include<bits/stdc++.h>
using namespace std;

const int maxn=3e3+5;

struct Idea
{
    int PMID;      //PM编号
    int startTime; //提出时间
    int priority;  //优先等级
    int costTime;  //所需时间
    int order;     //输入的序号
}idea[maxn];

int n,m,p;
int finishTime[maxn];  //每个Idea的完成时间
int programTime[maxn]; //每个程序员的空闲时刻
vector<Idea> PM_Idea[maxn];  //每个PM未完成的Idea,等待状态

// PM最想实现的Idea优先级
bool cmpPM(Idea a,Idea b)
{
    if(a.priority==b.priority)
    {
        if(a.costTime==b.costTime)
            return a.startTime<b.startTime;
        return a.costTime<b.costTime;
    }
    return a.priority>b.priority;
}

// 程序员挑选Idea的优先级
bool cmpTask(Idea a,Idea b)
{
    if(a.costTime==b.costTime)
        return a.PMID<b.PMID;
    return a.costTime<b.costTime;
}

// 对所有Idea按提出时间从小到大排序
bool cmpTime(Idea a,Idea b)
{
    return a.startTime<b.startTime;
}

int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for(int i=0;i<p;++i)
    {
        scanf("%d%d%d%d",&idea[i].PMID,&idea[i].startTime,&idea[i].priority,&idea[i].costTime);
        idea[i].order=i;
    }

    // 对所有Idea按提出时间从小到大排序
    sort(idea,idea+p,cmpTime);

    // currenTime:当前时间;cnt:完成Idea的数量;pre:上次未加入到等待序列(PM_Idea)中的idea位置
    int currentTime=1,cnt=0,last=0;
    while(cnt<p)
    {
        // 先把在当前时间之前提出的所有Idea加入到等待序列中
        for(int i=last;i<p;++i)
        {
            if(idea[i].startTime==currentTime)
            {
                int PMID=idea[i].PMID;
                PM_Idea[PMID].push_back(idea[i]); //加入等待序列
                sort(PM_Idea[PMID].begin(),PM_Idea[PMID].end(),cmpPM); //更新序列中Idea的顺序
                
                //进行到最后一个Idea时更新一下last的值
                if(i==p-1)
                    last=p;
            }
            else
            {
                last=i; //记录将要被提出的Idea的位置,下一次可以直接从此位置开始判断添加
                break;
            }
        }

        vector<Idea> wait_Idea; //程序员要选择的Idea序列
        // 为每个PM添加最想要完成的Idea
        for(int i=1;i<=n;++i)
            if(!PM_Idea[i].empty())
                wait_Idea.push_back(PM_Idea[i][0]);

        for(int i=0;i<m;++i)
        {
            // 如果当前程序员处于空闲状态,并且等待序列不为空的话
            if(programTime[i]<=currentTime&&!wait_Idea.empty())
            {
                // 对等待序列进行排序,使得优先级高的Idea排在最前面
                sort(wait_Idea.begin(),wait_Idea.end(),cmpTask);
                // 更新当前程序员的空闲时间
                programTime[i]=currentTime+wait_Idea[0].costTime;
                // 记录Idea的完成时间
                finishTime[wait_Idea[0].order]=programTime[i];
                
                int PMID=wait_Idea[0].PMID;
                // 从等待序列中将这个Idea删除
                PM_Idea[PMID].erase(PM_Idea[PMID].begin());
                // 从选择序列中将这个Idea删除
                wait_Idea.erase(wait_Idea.begin());
                // 更新选择序列,添加这个PM下一个想要完成的Idea
                if(!PM_Idea[PMID].empty())
                    wait_Idea.push_back(PM_Idea[PMID][0]);
                
                ++cnt;
            }
        }
        ++currentTime;
    }

    for(int i=0;i<p;++i)
        printf("%d\n",finishTime[i]);
    return 0;
}


编辑于 2019-04-27 16:59:00 回复(0)

这个题不难,思路十分容易想,问题是,要足够信心和耐心。

看过来~~~

发表于 2018-01-27 01:00:32 回复(6)
这个题是真的绕啊,要先按照PM的规则排序每个PM的idea然后空闲的程序员从每个PM优先级最高的idea里面挑选,写了半天就是不对,回去读题目发现自己的思路就是错的
发表于 2023-06-27 14:15:43 回复(0)

这个题的描述不是很容易让人看懂,我也是看着执行的预期输出反着推题干所表述的含义,将题目梳理并补充如下

思路

  • 有N个PM项目经理在时间轴上的不同时刻给 M个程序员提idea需求,idea拥有序号、优先级、提出时间、所需时间的属性。PM有多个需求的时候先自己PK,选出认为最优先的丢给程序员去做,在众多PM中,程序员资源优先也只能从所有PM过滤完的需求再次选所需时间最短的来做。
  • 大前提是程序员不知道未来时间的需求,不会做未来的idea需求,也就是只会从当前时刻以前的需求中进行挑选
  • 如果当前时间一个PM已经有多个idea需求提出,那么PM只能选出一个最优先的(题干描述的很隐蔽,这条是关键)
  • 给定的数据中,所有需求按时间顺序排序,每次处理时大于当前时间的过滤掉,小于当前时间的都有可能去处理
  • 过滤掉时间条件后,按照每个PM的各自的需求,各自排序(这道题的核心坑点就在这,读题目容易误解,如果每个PM不将自己的需求排好序选出一个出来,而是将所有的需求都丢给程序员,程序员自身理解的优先级规则,是按照所需时间多少来做的,那么一个PM的两个需求就有可能程序员先做时间少但优先级低的)
  • 所有PM都将自己最优先的需求列出后,程序员再从这个集合中选出要做的,没来得及做的需求会参与到下次比较中,下次比较有可能又被新的需求更高的优先级替代掉。

具体操作

  • 比较器
    • 时间顺序比较器
    • PM理解的优先级比较器
    • Programmer理解的优先级比较器
  • 集合
    1) 所有idea的集合
    2) 通过所有idea的集合过滤出小于当前时间的
    3) 从2中得出的按照PM各自选出最优先的得出新的集合
    4) 空闲的程序员从3中的集合,选出程序员理解的做先做的任务去做,剩余的任务将参与下一次第3步骤的比较
发表于 2022-05-18 17:06:28 回复(0)

写了好几个小时才对,挺绕的,看别人说这个题简单,可能是我太笨了。我要面试时写,肯定写不出来,题目都不一定能读明白。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef struct Task {
    int belong;
    int start;
    int priority;
    int need_time;
    int number;
    int end;
}Task;
Task A[3000], *B[3000];
int n, m, p;
class cmp {
    public:
        bool operator()(const Task *a, const Task* b) {
            return a->priority == b->priority ? (a->need_time == b->need_time? a->start > b->start : a->need_time > b->need_time) : a->priority priority;
        }
};
void solve() {
    // m 程序员
    priority_queue, greater> T;
    for(int i = 0; i < m; ++i) {
        T.push(0);
    }
    // p 对idea 进行排序
    sort(B, B+p, [](const Task* a, const Task* b) {
        return a->start start;
    });
    // 等待完成的idea
    int cnt = 0, idx = 0;
    priority_queue, cmp> ID[n+1];
    for(int i = 0; i < p; ++i) {
        int t = T.top();
        T.pop();
        while(idx start <= t) {
            ID[B[idx]->belong].push(B[idx]);
            ++idx;
            ++cnt;
        }
        if(cnt == 0) {
            Task * x = B[idx++];
            ID[x->belong].push(x);
            ++cnt;
            while(idx start == x->start) {
                ID[B[idx]->belong].push(B[idx]);
                ++idx;
                ++cnt;
            } 
        }
        int min_time = INT_MAX, iidx = -1;
        for(int i = 1; i <= n; ++i) {
            if(ID[i].size() > 0 && ID[i].top()->need_time < min_time) {
                min_time = ID[i].top()->need_time;
                iidx = i;
            }
        }
        Task * z = ID[iidx].top();
        t = max(t, z->start) + z->need_time;
        A[z->number].end = t;
        T.push(t);
        ID[iidx].pop();
        --cnt;
    }
    for(int i = 0; i < p; ++i) {
        printf("%d\n", A[i].end);
    }
}
int main() {
    scanf("%d%d%d", &n, &m, &p);
    for(int i = 0; i  < p; ++i) {
        scanf("%d%d%d%d",&A[i].belong, &A[i].start, &A[i].priority, &A[i].need_time);
        A[i].number = i;
        B[i] = &A[i];
    }
    solve();
}
编辑于 2022-05-14 14:44:06 回复(0)
给的示例里在时间3完成了最开始的两个idea之后,不应该去完成优先级高的吗,为什么会答案是先去完成提出时间早的?
发表于 2021-10-04 15:52:06 回复(0)
改了2天一直不对,原来是犯了个逻辑错误,对于优先级, 数字越低,优先级也越低,  我是按照数字越低,优先级越高搞得,竟然还能过30%..........
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int pmCount = sc.nextInt();
        int softCount = sc.nextInt();
        int ideaCount = sc.nextInt();
        sc.nextLine();

        List<Idea> ideas = new ArrayList<>();
        for (int i = 1; i <= ideaCount; i++) {
            Idea idea = new Idea();
            idea.id = i;
            idea.pmno = sc.nextInt();
            idea.submitTime = sc.nextInt();
            idea.order = sc.nextInt();
            idea.needTime = sc.nextInt();
            ideas.add(idea);
            sc.nextLine();
        }
        Map<Integer, Idea> completed = new HashMap<>();
        work(ideas, softCount, completed, ideaCount,pmCount);
        for (int i = 1; i <= ideaCount; i++) {
            System.out.println(completed.get(i).endTime);
        }
    }

    public static void sortForPM(List<Idea> ideas) {
        ideas.sort((i1, i2) -> {

            int seq1 = i2.order - i1.order;
            int seq2 = i1.needTime - i2.needTime;
            int seq3 = i1.submitTime - i2.submitTime;
            return seq1 != 0 ? seq1 : (seq2 != 0 ? seq2 : seq3);

        });
    }

    public static void selectBySubmitTime(Map<Integer, List<Idea>> pmIdeaMap, List<Idea> ideaList, int currTime) {

        for (Idea idea : ideaList) {
            if (idea.submitTime == currTime) {
                pmIdeaMap.get(idea.pmno).add(idea);
            }
        }
        for (int i = 1; i <= pmIdeaMap.size(); i++) {
                if (!pmIdeaMap.get(i).isEmpty()) {
                    sortForPM(pmIdeaMap.get(i));
            }
        }
    }

    public static void sortForSoft(List<Idea> ideas) {
        ideas.sort((i1, i2) -> {
            int seq1 = i1.needTime - i2.needTime;
            int seq2 = i1.pmno - i2.pmno;
            return seq1 != 0 ? seq1 : seq2;
        });
    }

    public static void work(List<Idea> ideaList, int softCount, Map<Integer, Idea> completed, int ideaCount,int pmCount) {
        Map<Integer, List<Idea>> pmIdeaMap = new HashMap<>();
        for (int j=1;j<=pmCount;j++){
            pmIdeaMap.putIfAbsent(j,new ArrayList<>());
        }

        int curTime = 0;
        List<Idea> working = new ArrayList<>();
        while (true) {
            if (completed.size() == ideaCount) {
                return;
            }
            curTime++;

            // add for pm
            selectBySubmitTime(pmIdeaMap, ideaList, curTime);
            // add time
            List<Idea> toDelete = new ArrayList<>();
            for (Idea idea : working) {
                if (curTime== idea.endTime) {
                    toDelete.add(idea);
                    completed.put(idea.id, idea);
                    softCount++;
                }
            }
            working.removeAll(toDelete);
            while (softCount > 0) {
                Idea idea=selectForSoft(pmIdeaMap);
                if (idea==null){
                    break;
                }
                idea.endTime = curTime + idea.needTime;
                softCount--;
                working.add(idea);
            }



        }

    }

    public static Idea selectForSoft(Map<Integer, List<Idea>> pmIdeaMap) {
        List<Idea> toWorkSet=new ArrayList<>();
        for (List<Idea> itemList : pmIdeaMap.values()) {
                if (itemList.size() > 0) {
                    toWorkSet.add(itemList.get(0));
                }
            }


        if(!toWorkSet.isEmpty()){
            sortForSoft(toWorkSet);
            Idea idea = toWorkSet.get(0);
            pmIdeaMap.get(idea.pmno).remove(idea);
            return idea;
        }

        return null;
    }

    static class Idea {

        public int id;
        public int pmno;
        public int submitTime;
        public int order;
        public int needTime;
        public int endTime;
    }

}


发表于 2020-08-27 12:41:03 回复(0)

题目的表述非常绕.仔细阅读并尝试理解题意.


我们应该为每个PM保持1个priority_queue,保存当前已经被提出来的idea.注意,程序员只能看到他的首个idea(程序员眼中的优先排名准则与pm不同!)

开一个完成时间的数组time_of_idea_completed记录每个idea的完成时间.

开一个数组time_to_finish_current_idea,其中time_to_finish_current_idea[i]的含义为编号为i(从1开始编号)的程序员手头上的idea还要处理多久.


设置一个变量current_time来保存当前时间

设置一个变量num_of_ideas_left记录当前时间点还有多少idea没有被分配给程序员.进入主循环的条件是还有任务没有被分配(一旦任务都被分配,就可以确定它们在什么时间被完成,就不需要继续模拟了)

传入的参数ideas按照时间升序排列(按照降序排列然后从尾部移出效率更高,但是没那么直观.本题数据规模不大,这样也可以通过)

另外设置一个

vector<priority_queue<idea> >ideas_has_been_proposed_group_by_pm,按照下标保存每个pm当前时间点已经提出的idea并且按照pm的优先级排名排成一个优先队列.C++的优先队列默认是大顶堆,即top()返回最大元,与Java相反.


进入主循环之后时间+1.我们考虑什么东西需要更新:可能有一些idea被提出来(判断条件为提出idea的时间<=current_time)我们将这些idea从ideas移出并加入对应的pm的优先队列中

开一个vector保存所有的”pm眼中的最重要idea”.(可能有一些pm的所有idea都已经被分配了那么他的队列为空)



新建一个临时vector保存每个pm眼中优先级最高的idea.注意,这个vector需要按照程序员的标准进行排序.

循环考虑每个程序员的变化.他手头上的idea剩余处理时间-1.一旦这个时间为0,表明他可以接手下一个idea.如果temp不为空那么他确实需要接手一个idea(可能出现空闲但是无事可做的情况,比如所有的idea都是时间10以后提出的.)

然后每次程序员按照程序员的标准找优先级最高的idea,就是temp[0]并接手.一旦一个idea被程序猿选中,从这个临时vector中删去这项任务,然后从这个idea对应的pm的优先队列中出队这个idea,然后如果pm的队列不空表示他还有没实现的idea,将这个pm的下一个idea放入临时vector



#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<iostream>
#include<list> 
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
class idea {
public:
	int index;
	int pm_num;
	int proposed_time;
	int priority;
	int time_needed;

	idea(int index, int pm_num, int proposed_time, int priority, int time_needed)
	{
		this->index = index;
		this->pm_num = pm_num;
		this->proposed_time = proposed_time;
		this->priority = priority;
		this->time_needed = time_needed;
	}
	bool operator<(const idea& idea2) const {
		if (this->priority < idea2.priority)return true;
		else if (this->priority > idea2.priority)return false;

		if (this->time_needed > idea2.time_needed)return true;
		else if (this->time_needed < idea2.time_needed)return false;

		return(this->proposed_time > idea2.proposed_time);
	}
};

bool cmp_time(idea a, idea b)
{
	return a.proposed_time < b.proposed_time;
}

bool cmp_programmer(idea idea1, idea idea2)
{
	
	if (idea1.time_needed < idea2.time_needed)return true;
	else if (idea1.time_needed > idea2.time_needed)return false;


	return(idea1.pm_num < idea2.pm_num);
}

vector<int> proceed(int n, int m, int p, vector<idea>&ideas)
{
	int num_of_ideas_left = p;
	sort(ideas.begin(), ideas.end(), cmp_time);
	vector<int> ans;
	vector<priority_queue<idea> >ideas_has_been_proposed_group_by_pm(n+1);

	vector<vector<idea> >ideas_to_be_proposed_group_by_pm(n+1);

	
	int time_to_finish_current_idea[3010];
	int time_of_idea_completed[3010];
	for (int i = 0; i < 3010; i++) {
		time_to_finish_current_idea[i] = 0;
		time_of_idea_completed[i] = 0;
	}
	int current_time = 0;

	

	while (num_of_ideas_left) {
		current_time++;
		int index = 0;
		while (index < ideas.size() && ideas[index].proposed_time <= current_time)index++;
		
		for (int i = 0; i < index; i++)
			ideas_has_been_proposed_group_by_pm[ideas[i].pm_num].push(ideas[i]);
		ideas.erase(ideas.begin(), ideas.begin() + index);

		

		vector<idea>temp;
		for (int i = 1; i <= n; i++)
			if (!ideas_has_been_proposed_group_by_pm[i].empty())
				temp.push_back(ideas_has_been_proposed_group_by_pm[i].top());
		sort(temp.begin(), temp.end(), cmp_programmer);


		int i = 1;
		while (  i <= m) {
			if (time_to_finish_current_idea[i] > 0)
				time_to_finish_current_idea[i]--;
			if(time_to_finish_current_idea[i]==0&& !temp.empty())
			 {
				idea idea0 = temp[0];
				time_to_finish_current_idea[i] = idea0.time_needed;
				temp.erase(temp.begin(), temp.begin() + 1);
				ideas_has_been_proposed_group_by_pm[idea0.pm_num].pop();
				if (!ideas_has_been_proposed_group_by_pm[idea0.pm_num].empty()) {
					temp.push_back(ideas_has_been_proposed_group_by_pm[idea0.pm_num].top());
					sort(temp.begin(), temp.end(), cmp_programmer);
				}
				time_of_idea_completed[idea0.index] = current_time + idea0.time_needed;
				num_of_ideas_left--;
			}
			i++;
		}
	}
	for (int i = 1; i <= p; i++)
		ans.push_back(time_of_idea_completed[i]);
	return ans;
}

int main() {
	/*
	int n = 2, m = 2, p = 5;
	idea idea1(1, 1, 1, 1, 2);
	idea idea2(2, 1, 2, 1, 1);
	idea idea3(3, 1, 3, 2, 2);
	idea idea4(4, 2, 1, 1, 2);
	idea idea5(5, 2, 3, 5, 5);
	vector<idea>ideas;
	ideas.push_back(idea1);
	ideas.push_back(idea2);
	ideas.push_back(idea3);
	ideas.push_back(idea4);
	ideas.push_back(idea5);
	vector<int>ans = proceed(n, m, p, ideas);
	
	for (int temp : ans)printf("%d\n", temp);
	getchar();
	*/
	int n, m, p;
	int pm_num;
	int proposed_time;
	int priority;
	int time_needed;
	cin >> n >> m >> p;
	vector<idea>ideas;
	for (int i = 0; i < p; i++) {
		cin >> pm_num >> proposed_time >> priority >> time_needed;
		idea idea_temp(i + 1, pm_num, proposed_time, priority, time_needed);
		ideas.push_back(idea_temp);
	}
	vector<int>ans = proceed(n, m, p, ideas);

	for (int temp : ans)printf("%d\n", temp);
	return 0;
}


编辑于 2019-09-19 08:15:39 回复(0)
python3 是我理解错误吗?请大佬指点,为什么1000个idea的无法通过,而且还不知道正确结果怎么看


#!/usr/bin/python
# -*- coding: utf-8 -*-
if __name__=='__main__':
    N, M, P = [int(i) for i in input().split(' ')]
    ideas = []
    for j in range(P):
        ideas.append([int(v) for v in input().split(' ')])
    tmp = ideas[:]
    ideas.sort(key=lambda v: (v[1], v[2], v[3], v[0]))
    Per = [0]*M
    res = []
    while ideas:
        print(ideas)
        if 0 in Per:  #0表示程序员的人数比所提ideas数目多,可以按idea的提出时间先后顺序进行处理
            seq = Per.index(min(Per))
            idea = ideas.pop(0)
            t_out, t_spend = idea[1], idea[3]
            Per[seq] = t_out+t_spend
            res.append({Per[seq]: idea})
        else:  #如果每个程序员都已经处理过任务,就需要优先考虑优先级顺序,而不是时间顺序
            flag = 0  #用来判断在程序员工作期间是否有新的idea加入
            for _, time_out, _, _ in ideas:
                if time_out < min(Per):
                    flag = 1
                    break
            if flag == 0:  #0表示在程序员完成某个idea之前没有新的idea加入,则等待idea,然后按时间顺序处理
                ideas.sort(key=lambda v: (v[1], v[2], v[3], v[0]))
                seq = Per.index(min(Per))
                idea = ideas.pop(0)
                Per[seq] = idea[1] + idea[3]
                res.append({Per[seq]: idea})
            if flag == 1:  #1代表在某个程序员完成某个idea之前有新的idea加入,则根据【优先级,所需时间,PM号】进行排序,再出队处理
                t1 = []
                for m in ideas:
                    if m[1] < min(Per):
                        t1.append(m)
                t1.sort(key=lambda v: (v[2], v[3], v[0]))
                seq = Per.index(min(Per))
                value = t1.pop(0)
                ideas.remove(value)
                Per[seq] = Per[seq] + value[3]
                res.append({Per[seq]: idea})
    for k1 in tmp:
        for t in res:
            for v, k2 in t.items():
                if k2 == k1:
                    print(v)
                    break

编辑于 2019-07-22 19:39:52 回复(3)
用python写了个,为什么跑过了10%后报语法或者字符数组越界的错误?

data = input()
m = int(data.split()[1])
p = int(data.split()[2])
employee = []
i = 0
time = 0
ideas = []
best_ideas = []
ideas_q = []
while p > i:
    s = input()
    ideas.append([int(s.split()[0]), int(s.split()[1]), int(s.split()[2]), int(s.split()[3])])
    i += 1
for j in ideas:
    a = True
    for k in ideas_q:
        if j[0] == k[0][0]:
            k.append(j)
            a = False
    if a:
        ideas_q.append([j])

i = 0
while m > i:
    employee.append([0])
    i += 1

while p > 0:
    time += 1
    max = []
    for i in employee:
        if i[0] != 0:
            i[0] -= 1
    while [0] in employee and p > 0:
        for j in ideas_q:
            a = False
            for k in j:
                if k.__len__() != 5 and time >= k[1]:
                    max = k
                    a = True
                    break
            for k in j:
                if k.__len__() != 5 and time >= k[1]:
                    if k[2] >= max[2]:
                        if max[2] != k[2]:
                            max = k
                        elif max[3] >= k[3]:
                            if max[3] != k[3]:
                                max = k
                            elif max[1] > k[1]:
                                max = k
            if a:
                best_ideas.append(max)
        max = best_ideas[0]
        for k in best_ideas:
            if max[3] >= k[3]:
                if max[3] != k[3]:
                    max = k
                elif max[0] > k[0]:
                    max = k
        max.append((time + max[3]))
        p -= 1
        for i in employee:
            if i == [0]:
                i[0] += max[3]
                break
        best_ideas.clear()

for i in ideas:
    print(i[4])

发表于 2019-04-11 20:07:39 回复(1)
看题看了半天,我们先捋一捋。
首先重要的是idea,每个idea都包含了
1.对应PM的id 2.提出时间 3.优先级 4.需要的时间
2.对于PM来说,他们产生idea,PM有自己的规则来选择最想完成的idea。
3.对于程序员,首先要看自己是否有空,然后根据此时的所有PM最想完成的idea,
根据自己的规则选取idea来做,同时更新对应程序员的空闲时刻。
这里面有个十分重要的变量就是时间,对于时间的控制一定要注意。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct idea{
    int PM_id;
    int post_time;
    int priority;
    int cost_time;
    int order; //  idea 序号
}ideas[3001];

int N,M,P;
int finish_time[3001];//完成每个idea的时间
int program_time[3001];//程序员空闲时刻
vector<idea> PM_idea[3001];//每个PM某时刻所拥有的未完成的idea

 bool cmp_post(const idea &a,const idea &b){
     return a.post_time<b.post_time;
 }
 //PM的排序
bool cmp_priority(const idea &a,const idea &b){
    if(a.priority!=b.priority)
        return a.priority>b.priority;
    else if(a.cost_time!=b.cost_time)
        return a.cost_time<b.cost_time;
    return a.post_time<b.post_time;
}
//程序员的排序
bool cmp_cost(const idea &a,const idea &b){
    if(a.cost_time!=b.cost_time)
        return a.cost_time<b.cost_time;
    return a.PM_id<b.PM_id;
}

int main(){
    cin>>N>>M>>P;
    int pm,post,por,cos;
    for(int i = 0;i<P;i++){
        cin>>pm>>post>>por>>cos;
        ideas[i] = {pm-1,post,por,cos,i};
    }
    sort(ideas,ideas+P,cmp_post);//按照时间排序
    int nowtime = 1,cnt = 0,last = 0;//nowtime 当前时间 cnt已完成任务 last下一次添加任务的起点
    while(cnt<P){

        for(int i = last;i<P;i++){
            if(ideas[i].post_time==nowtime){
                //个对应的PM添加这个idea,再根据PM判断规则排序
                PM_idea[ideas[i].PM_id].push_back(ideas[i]);
                sort(PM_idea[ideas[i].PM_id].begin(),PM_idea[ideas[i].PM_id].end(),cmp_priority);
                if(i==P-1)
                    last = P;
            }else{
                last = i;
                break;
            }
        }
        //选取每个PM最想完成的idea
        vector<idea>PM_pro;
        for(int i =0;i<N;i++){
            if(!PM_idea[i].empty()){
                PM_pro.push_back(PM_idea[i][0]);
            }
        }

        for(int i = 0;i<M;i++){
            //程序员i空闲并且此时有idea
            if(program_time[i]<=nowtime&&!PM_pro.empty()){
                //按照程序员的规则来排序
                sort(PM_pro.begin(),PM_pro.end(),cmp_cost);
                program_time[i] = nowtime+PM_pro[0].cost_time;
                finish_time[PM_pro[0].order] = program_time[i];
                PM_idea[PM_pro[0].PM_id].erase(PM_idea[PM_pro[0].PM_id].begin());
                if(!PM_idea[PM_pro[0].PM_id].empty())
                    PM_pro.push_back(PM_idea[PM_pro[0].PM_id][0]);
                PM_pro.erase(PM_pro.begin());
                cnt++;
            }
        }
        nowtime++;
    }
    for(int i = 0;i<P;i++){
        cout<<finish_time[i]<<endl;
    }
    return 0;
}

发表于 2019-04-01 18:31:58 回复(0)