CCF 201903-4消息傳遞接口(隊列)

原文鏈接

我的個人博客

原題鏈接

CCF 201903-4消息傳遞接口

思路

  主要的思路是利用隊列來存儲每一個進程的收發指令。一旦找到匹配的指令,則將這一對出隊列。直到某一次找不到匹配的指令了,退出循環。再判斷是不是所有的進程對應的收發指令隊列都爲空。如果全部爲空,則該程序不存在死鎖,否則進程存在死鎖。
  因爲每一個進程有的收發指令的個數是不同的,因此需要處理這樣不定數的輸入。這裏用到了stringstream來進行處理。即

getline(cin,line);//輸入一行字符串
stringstream ss(line);
while(ss >> ins){//進行字符串分割。並賦值給ins
      cout<<ins<<endl;
}

  另外還要值得注意的是,進程n的最多可達10的4次方。因此n可能不止一位數,所有在做題的過程中,不能默認每一個收發指令的長度是2。這樣就大錯特錯了!

#include <bits/stdc++.h>
using namespace std;
struct node{
	bool RS;//標記狀態,接還是發
	int num;//進程號
	node(bool r,int n){
		RS = r;
		num = n;
	} 
};
int main(){
	int T,n;
	cin>>T>>n;
	getchar();//喫掉換行符 
	
	while(T--){
		//依次判斷T個程序是否存在死鎖
		vector<queue<node>> v(n); // 用戶存放進程
		string line,ins;
		//初始化各進程的首發指令 
		for(int i=0;i<n;i++){
			getline(cin,line);//輸入一行字符串
			stringstream ss(line);
			while(ss >> ins){
//				cout<<ins<<endl;
				bool RS = ins[0] == 'R' ? 0 : 1;//R爲0
				//進程號不一定在0-9,所以進程號可能是多位!!! 
				int num = stoi(ins.substr(1));//取出進程號
				v[i].emplace(RS,num);//c++11新特性。相當於v.push(node{RS,num}),比起push內存消耗更少 
//				v[i].push(node{RS,num});//實測這兩個好像都可以 
			} 
		}
		bool flag = true;//表示是否有匹配的
		while(flag){
			bool isfind = false; 
			//一直去找匹配的收發指令
			for(int i=0;i<n;++i){
				if(v[i].empty()) continue;
				node tmp = v[i].front();//取出第
				int target = tmp.num;//取出收發指令對應的進程號
				if(!v[target].empty()){//收發指令匹配 
					if(v[target].front().RS != tmp.RS  && v[target].front().num == i ){
						v[target].pop();
						v[i].pop();//出隊列 
						isfind = true;
					}
					
				}
			} 
			//找不到匹配的元素了 
			if(isfind == false){
				break;
			}
		}
		flag = true;
		//判斷指令全部匹配完。即判斷隊列是否爲空即可
		for (int i=0;i<n;++i){
			if(!v[i].empty()){
				flag = false;
				break;
			}
		}
		if(flag){
			cout<<0<<endl;
		}else{
			cout<<1<<endl;
		}
	}
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章