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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章