CCF认证 201903-4消息传递接口

本文介绍了一种使用队列和递归方法实现的进程间通讯模拟算法,并提供了一份100分的代码示例。该算法能够有效处理多个进程间的接收(R)与发送(S)操作,避免死锁情况的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

CCF认证 201903-4消息传递接口题目描述

方法一:用n个队列来维护n个进程,利用递归思想解决

100分代码:

#include<bits/stdc++.h>
using namespace std;
const int N=10010;
struct node{
	char aa;
	int bb;
};
queue<node>q[N];
int wait[N];//用来记录当前的进程是处于阻塞状态还是就绪状态
//0代表就绪,1代表阻塞 
int t,n;
int deal(int k);
int rec(int from,int to);
int send(int from,int to);
/*void tostr(string line,char ch,int idd){//以ch分割字符串 
	int t;
	node p;
    for(t = line.find(ch); t != string::npos; t = line.find(ch))
    {
        string ss=line.substr(0,t);
        p.ch=ss[0];
        p.id=(ss[1]-'0');
        q[idd].push(p);
        line = line.substr(t+1);
    }
    p.ch=line[0];
    p.id=(line[1]-'0');
    q[idd].push(p);	
    return;
}*/
int deal(int k){//k进程的处理过程 
	if(wait[k]==1) return -1;//处于阻塞状态,不能执行
	if(q[k].empty()) return 0;//队列为空,不能执行
	//char ch=q[k].front().ch;
	//int id=q[k].front().id;
	node p=q[k].front();
	if(p.aa=='R'){
		wait[k]==1;
		if(rec(k,p.bb)==-1) return -1;
		//如果成功接收 
		
		q[k].pop();
		wait[k]=0;
		if(deal(k)==-1) return -1;//继续处理该进程 
		return 0;
	}else if(p.aa=='S'){
		wait[k]=1;
		if(send(k,p.bb)==-1) return -1;
		q[k].pop();
		wait[k]=0;
		if(deal(k)==-1) return -1;//继续处理该进程 
		return 0;
	}
}
int send(int from,int to){//from给to发送消息 
	if(wait[to]==1) return -1;
	if(q[to].empty()) return -1;
	//char ch=q[to].front().ch;
	//int id=q[to].front().id;
	node p=q[to].front();
	if(p.aa=='R'){
		//wait[to]=1;
		if(p.bb==from){
			//wait[to]=0;
			q[to].pop();
			return 0;
		}
		wait[to]=1;//无法执行,被阻塞
		if(rec(to,p.bb)==-1) return -1;//递归执行该进程时无法执行
		wait[to]=0;//递归结束后,将其状态还原
		q[to].pop();//弹出
		//观察之前的进程是否可以处理
		if(send(from,to)==0) return 0;
		return -1; 
	}else if(p.aa=='S'){//两个都是发送状态,无法进行处理 
		wait[to]=1;
		if(send(to,p.bb)==-1) return -1;
		wait[to]=0;
		q[to].pop();
		if(send(from,to)==0) return 0;
		return -1;
	}
	return -1;
}
int rec(int from,int to){//from接受来自to的消息 
//第一个是自身的参数,第二个是对方的参数 
	if(wait[to]==1) return -1;
	if(q[to].empty()) return -1;
	//char ch=q[to].front().ch;
	//char id=q[to].front().id;
	node p=q[to].front();
	if(p.aa=='R'){
		wait[to]=1;
		if(rec(to,p.bb)==-1) return -1;
		wait[to]=0;
		q[to].pop();
		if(rec(from,to)==0) return 0;
		return -1;
	}else if(p.aa=='S'){//可能相互抵消
	    //wait[to]=1;
		if(p.bb==from){
			//wait[to]=0;
			q[to].pop();
			return 0;
		}
		wait[to]=1;
		if(send(to,p.bb)==-1) return -1;
		wait[to]=0;
		q[to].pop();
		if(rec(from,to)==0) return 0;
		return -1;		
	}
	return -1;
}
int main(){
	//std::ios::sync_with_stdio(false);//优化
	scanf("%d%d",&t,&n);
	getchar();
	for(int k=0;k<t;k++){
		int flag=0;
		memset(wait,0,sizeof(wait));
		for(int i=0;i<n;i++){
	    	while(!q[i].empty()) q[i].pop();
		}
		for(int j=0;j<n;j++){ //存储进程的消息队列
			string line;
			getline(cin,line);
			istringstream ss(line);
			string tmp;
			while(ss>>tmp){
				node p;
				p.aa=tmp[0];
				tmp=tmp.substr(1);
				p.bb=stoi(tmp);
				q[j].push(p);
			}
		}

		/*char c=' ';
		for(int i=0;i<n;i++){//输入信息的处理,每个进程的信息都
        //放到队列中,共有n个进程 
			getline(cin,s);
			//cout<<"s="<<s<<endl;
			tostr(s,c,i);
		}*/
		for(int i=0;i<n;i++){
			if(!q[i].empty()){
				if(deal(i)==-1){
					flag=1;
					break;
				}
			}
			 
		}
		cout<<flag<<endl;
	}
		
	return 0;
}
/*
2 3
R1 S1
R2 S0 R0 S2
S1 R1
R1
R2 S0 R0
S1 R1
*/
/*
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
*/

方法二:枚举遍历:运行超时:60分

#include<bits/stdc++.h>
using namespace std;
const int N=10010;
struct node{
	char ch;
	int id;
};
queue<node>q[N];
//vector<queue<node>>ve[N];
int t,n;
void tostr(string line,char ch,int idd){//以ch分割字符串 
	int t;
	//ve[idd].clear(); 
	node p;
    for(t = line.find(ch); t != string::npos; t = line.find(ch))
    {
        string ss=line.substr(0,t);
        //cout<<"ss="<<ss[0 ]<<endl;
        p.ch=ss[0];
        string tt=ss.substr(1);
        p.id=stoi(tt);
        q[idd].push(p);
        line = line.substr(t+1);
    }
    p.ch=line[0];
    string tt=line.substr(1);
    p.id=stoi(tt);
    //cout<<p.ch<<"whf"<<p.id<<endl;
    q[idd].push(p);
    //cout<<"line="<<line<<endl;
    //ve[idd].push_back(q[idd]);
    //cout<<"size="<<q[idd].size()<<endl; 
	//cout<<"idd="<<idd<<endl;
	/*while(!q[idd].empty()){
		cout<<q[idd].front().ch<<q[idd].front().id<<endl;
		q[idd].pop();
		}*/
		
    return;
}
int main(){
	cin.tie(0);//取消cin的同步
    cout.tie(0);//取消cout的同步
	
	scanf("%d%d",&t,&n);
	getchar();
	string s;
	while(t--){
		for(int i=0;i<n;i++){
	    	while(!q[i].empty()) q[i].pop();
		}
		char c=' ';
		for(int i=0;i<n;i++){//输入信息的处理,每个进程的信息都
		 
        //放到队列中,共有n个进程 
			getline(cin,s);
			//cout<<"s="<<s<<endl;
			tostr(s,c,i);
		}
		/*for(int i=0;i<n;i++){
			cout<<"i="<<i<<endl;
			for(int j=0;j<q[i].size();j++){
				cout<<q[i].front().ch<<q[i].front().id<<endl;
				q[i].pop();
			}
		}*/
	    //依次遍历进程,可以完成的步骤去掉
	    /*for(int j=0;j<n;j++){ //存储进程的消息队列
			string line;
			getline(cin,line);
			istringstream ss(line);
			string tmp;
			while(ss>>tmp){
				node p;
				p.ch=tmp[0];
				tmp=tmp.substr(1);
				p.id=stoi(tmp);
				q[j].push(p);
			}
		}*/
	      
	        int x=n;
	        while(true){
	        int flag=1;
	    	for(int i=0;i<n;i++){
			    char ch1,ch2;
			    int index1,index2;
			    if(q[i].empty()) continue;
				ch1=q[i].front().ch;
				index1=q[i].front().id;
				for(int j=0;j<n;j++){
					if(q[j].empty()) continue;
					if(i!=j){
						ch2=q[j].front().ch;
			        	index2=q[j].front().id;
			        	//cout<<"ch1="<<ch1<<" "<<"ch2="<<ch2<<" "<<"index1="<<index1<<" "<<"index2="<<index2<<endl;
			        	if(ch1!=ch2&&index1==j&&index2==i){
			        		//cout<<"i="<<i<<" "<<"j="<<j<<endl;
			        		flag=0;
			    	    	q[i].pop();
			    	    	//if(q[i].empty())x--;
			    	    	q[j].pop();
			    	    	//if(q[j].empty())x--;
			    	    	break;
				    	}
					}
				}
			}
			
			if(flag) break;}
			int g=0;
			for(int i=0;i<n;i++){
				if(!q[i].empty()){
					g=1;
					break;
				}
			}
			cout<<g<<endl;
}

	return 0;
}
/*
2 3
R1 S1
R2 S0 R0 S2
S1 R1
R1
R2 S0 R0
S1 R1
*/
/*
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
*/

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值