出处:https://blog.csdn.net/pb1995/article/details/48736317
题目链接:https://vjudge.net/contest/231030#problem/M
又是一道简单的流程模拟题, 注意看题抠细节
关键在于安排任务时是以人为主体还是以待办的事件为循环主体
这要根据题目的某些要求来决定
这道题目要求有冲突时需要选出lasttime最早的, 否则就选出id最小的
乍一看感觉是要以待办事件为主体来找人的
但是写到一半发现写不下去了, 因为在找到一个available的人的时候, 还需要跟其他available的人作对比,
也就是说先要找出所有available的人, 再从这些人当中选出一个真正available的人来安排给他工作
但是这样就大大增加了题目的复杂度
解决这个问题的方案就是, 以人为循环主体来找工作( 其实题目里也有明确的暗示了, 只是之前没当一回事..)
按照题目的要求(两个要求, 自己定义一个比较函数)把存储人的数组先进行排序,
对排序后的人依次找一个topic做就 行了
结束的时机是所有人都不在工作并且所有工作都分配完了
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <cassert>
#include <iomanip>
using namespace std;
const int MAXN = 20+1;
typedef long long LL;
#define DEBUG2
/*
uva 12504
*/
struct topic{
int id;
int num;
int beforeFirst;
int needed;
int between;
int last;
} topics[MAXN];
struct person{
int id;
int last;
int doing;
int cover;
int aval[MAXN];
bool isWorking;
} persons[MAXN];
bool operator<(const person & p1, const person & p2){
if( p1.last!=p2.last ) return p1.last<p2.last;
return p1.id<p2.id;
}
int T,N,Time;
int tq[MAXN];
bool isEnd;
map<int,int> mark;
int Getwork(int personNum){
int i = personNum;
for(int j=0; j<persons[i].cover; j++){
int n = persons[i].aval[j];
if( tq[n]>0 ){
return n;
}
}
return -1;
}
void update(){
for(int i=0; i<T; i++){
if( topics[i].num>0 ){
if( Time==topics[i].beforeFirst ){
tq[i]++;
topics[i].num--;
topics[i].beforeFirst = -1;
topics[i].last = Time;
}
if( Time-topics[i].last==topics[i].between && topics[i].beforeFirst==-1 ){
tq[i]++;
topics[i].num--;
topics[i].last = Time;
}
}
}
sort(persons,persons+N);
for(int i=0; i<N; i++){
if( persons[i].isWorking ){
int doing = mark[persons[i].doing];
if( Time-persons[i].last==topics[doing].needed ){
persons[i].isWorking = false;
persons[i].doing = -1;
}
}
}
for(int j=0; j<T; j++){
for( int i=0; i<N; i++ ){
if( !persons[i].isWorking && j<persons[i].cover ){
int n = mark[persons[i].aval[j]];
if( tq[n]>0 ){
tq[n]--;
persons[i].doing = topics[n].id;
persons[i].isWorking = true;
persons[i].last = Time;
}
}
}
}
}
void check(){
isEnd = true;
for(int i=0; i<N; i++){
if( persons[i].isWorking ) isEnd = false;
}
for(int i=0; i<T; i++){
if( topics[i].num>0 ) isEnd = false;
}
}
void initial(){
memset(tq,0,sizeof(tq));
memset(topics,0,sizeof(topics));
memset(persons,0,sizeof(persons));
mark.clear();
isEnd = false;
Time = 0;
}
void test(){
printf("Time = %d\n",Time);
printf("%-8s %-8s %-8s %-8s\n","id","isWorking","doing","last");
for(int i=0; i<N; i++){
printf("%-8d %-8d %-8d %-8d\n",persons[i].id, persons[i].isWorking, persons[i].doing, persons[i].last);
}
for(int i=0; i<T; i++){
printf("%d:%d\t",topics[i].id,tq[i]);
}
printf("\n----------------\n");
return ;
}
int main(){
// freopen("input2.txt","r",stdin);
scanf("%d ",&T);
int Case = 0;
while( T!=0 ){
initial();
int n;
for(int i=0; i<T; i++){
cin >> topics[i].id >> topics[i].num >> topics[i].beforeFirst ;
cin >> topics[i].needed >> topics[i].between;
mark[topics[i].id] = i;
}
scanf("%d ",&N);
for(int i=0; i<N; i++){
cin >> persons[i].id >> persons[i].cover;
for(int j=0; j<persons[i].cover; j++){
cin >> persons[i].aval[j]; // 输入topic id
}
persons[i].last = persons[i].doing = -1;
}
while( !isEnd ){
update();
check();
// test();
Time++;
}
printf("Scenario %d: All requests are serviced within %d minutes.\n",++Case,Time-1);
scanf("%d ",&T);
}
return 0;
}