uva 822

原题

又是一道简单的流程模拟题, 注意看题抠细节

关键在于安排任务时是以人为主体还是以待办的事件为循环主体

这要根据题目的某些要求来决定

这道题目要求有冲突时需要选出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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值