201903-4 消息传递接口 100分 187ms

点击前往试题目录:https://blog.csdn.net/best335/article/details/99550556
在这里插入图片描述
思路:为了更加效率,从头遍历进程查看队首任务,查看该任务对应的进程是否是当前进程匹配的任务,如果是,那么对这两个进程做删除队首任务操作,同时从这两个进程较小的继续重新执行任务(贪心),直到遍历到结束也没有匹配到进程或者全部匹配完毕。

#include<iostream>
#include<queue>
#include<map>
using namespace std;
typedef pair<int,int> P;
int main(){
	std::ios_base::sync_with_stdio(false),cin.tie(NULL); //加速输入处理
	int T,n;
	string s;
	cin>>T>>n,cin.get();
	for(int l=0,f=1,N=0;l<T;++l,f=1,N=0){//遍历样本样本
		map<int,deque<P> > M;//存储全部进程的任务队列
		for(int i=0;i<n;++i){
			getline(cin,s);
			deque<P>&q=M[i];//存储当前进程任务的队列 
			int j=0,nj=s.size(),t,idx;
			while(j<nj){
				t=j,idx=++j;//t 任务类型
				while(j<nj&&s[j]!=' ')++j;
				string num=s.substr(idx,j-idx);
				int no=0;
				for(int k=0,nk=num.size();k<nk;++k) no=no*10+(num[k]-'0');//任务对应的进程号
				q.push_back(P(s[t]=='R'||s[t]=='r'?1:0,no)),++N;
				while(j<nj&&s[j]==' ')++j;
			}
			if(q.empty()) M.erase(M.find(i));//如果队列任务空 删除进程
		}
		while(N>0&&f==1){//如果没有全部匹配到
			f=0;//匹配标志位
			for(map<int,deque<P> >::iterator it=M.begin(),itf;it!=M.end();){
				deque<P> & q=it->second;
				const int x=it->first,y=q.front().second,&t=q.front().first;
				if((itf=M.find(y))!=M.end()){
					deque<P> & _q=itf->second;
					const int &_y=_q.front().second,&_t=_q.front().first;
					if(x==_y&&t!=_t){//判断是否匹配 匹配后弹出两进程队首 如果队列为空 删除该进程 减少查找容量
						q.pop_front(),_q.pop_front(),f=1,N-=2;
						if(x>y){
							if(q.empty()) it=M.erase(it);
							if(_q.empty()) itf=M.erase(itf);
							it=itf;//取更小的进程重新继续遍历
						}
						else{
							if(_q.empty()) itf=M.erase(itf);
							if(q.empty()) it=M.erase(it);
						}
					}
					else ++it;
				}
				else ++it;
			}
		}
		cout<<(N==0?0:1)<<endl;
	}
	return 0;
}
/*
3 2
R1 S1
S0 R0
R1 S1
R0 S0
R1 R1 R1 R1 S1 S1 S1 S1
S0 S0 S0 S0 R0 R0 R0 R0 



2 3
R1 S1
R2 S0 R0 S2
S1 R1
R1
R2 S0 R0
S1 R1
*/
发布了107 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/best335/article/details/100112203