CCF CSP认证201903-4 消息传递接口(模拟)

201903-4 消息传递接口

题目
在这里插入图片描述在这里插入图片描述在这里插入图片描述

思路

40分运行错误,待更。
用队列数组储存各个进程的指令。从任意进程的队首指令开始,递归查找能匹配的指令,查到便将该指令对出列。


(2019.9.12)
读数的时候出错了。。。想当然把指令编号当成1位。(逃

这么做效率挺低的,多了很多重复查找。

更好的方法是,让刚执行完一对指令的进程优先执行下一条指令。

AC代码如下

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct comand{
 	int x;
 	bool flag;
};
queue<comand> cmd[10005];
int n,T;
bool vis[10005];

bool unlocked(int i,int x,bool f){//递归查找可执行的指令 
 	if(vis[x]) return false;//避免绕圈
 	vis[x]=true;
 	if(!cmd[x].empty()){
 		int t=cmd[x].front().x;
  		bool ff=cmd[x].front().flag;
  		if(t==i){
  			if(ff==f) return false;//指令不匹配 
   			cmd[i].pop();//找到可执行的指令,弹出 
   			cmd[x].pop();
	   		return true;
	 	}
  		return unlocked(x,t,ff);//递归找下一个
 	}
 	return false;//没有与之配对的指令 
}

int main(){
 	scanf("%d%d",&T,&n);
 	getchar();
 	while(T--){
  		for(int i=0;i<n;i++){//输入
   			while(!cmd[i].empty()) cmd[i].pop();//注意要把队列清空
   			char c=getchar();//读入'S'、'R' 
  			 while(c!='\n'){
  			 	int x=0;
    				char d=getchar();
    				while(d>='0'&&d<='9'){//读入x
     					x=x*10+d-'0';
     					d=getchar();
    				}
    				cmd[i].push((comand){x,(c=='S')});//存指令
    				if(d==-1||d=='\n') break;
    				c=getchar();//读入'S'、'R' 
   			}
  		}
  		int i;
  		for(i=0;i<n;i++){//遍历所有进程
   			while(!cmd[i].empty()){
    				int x=cmd[i].front().x;
    				bool f=cmd[i].front().flag;
    				memset(vis,0,sizeof(vis));
    				vis[i]=true;
    				if(unlocked(i,x,f)==false) break;
   			}
   			if(!cmd[i].empty()) break;//发生了死锁 
  		}
  		printf("%d\n",i<n);
 	}
 	return 0;
}

优化
在这里插入图片描述
把unlocked函数改一下,时间降了5/6。

bool unlocked(int i,int x,bool f){//递归查找可执行的指令 
 	if(vis[x]) return false;
 	vis[x]=true;
 	if(!cmd[x].empty()){
  		int t=cmd[x].front().x;
  		bool ff=cmd[x].front().flag;
  		if(t==i){
   			if(ff==f) return false;//指令不匹配 
   			cmd[i].pop();//找到可执行的指令,弹出 
   			cmd[x].pop();
   			return true;
 	 	}
  		if(unlocked(x,t,ff)){//执行完了一对指令,从x开始递归查找下一对指令
   			do{
    				if(cmd[x].empty()) return true;
    				memset(vis,0,sizeof(vis));
    				t=cmd[x].front().x;
    				ff=cmd[x].front().flag;
    				vis[x]=true;
   			}while(unlocked(x,t,ff));
  		}
 	}
 	return false;//没有与之配对的指令 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值