1. 程式人生 > 其它 >CSP201903-4 訊息傳遞介面(模擬)

CSP201903-4 訊息傳遞介面(模擬)

挺nt的一個題,除了嗯模擬沒想到更好的辦法...大概就是每次遍歷一遍所有的程序的當前通訊,如果

可以收發則直接收發,然後更新當前通訊;如果所有程序都不能收發則死鎖。細節見程式碼。

#include <bits/stdc++.h>
using namespace std;	
int t, n;
struct node {
	char op;//這個通訊是收還是發
	int to;//這個通訊發到的/從哪裡接收來的 id
	int id;//這個通訊的程序id
};
vector<node> process[100005];
int p[1000005];//程序的當前通訊位置

int tran(string s) {//字串轉數字,也可以stringstream
	int ans = 0;
	for(int i = 0; i < s.size(); i++) {
		ans *= 10;
		ans += (s[i] - '0');
	}
	return ans;
}
bool sisuo = 0;
signed main() {
	cin >> t >> n;
	getchar();//必須先讀換行符
	while(t--) {
		sisuo = 0;
		for(int i = 0; i < n; i++) {
			process[i].clear();
			p[i] = 0;
		}
		for(int i = 0; i < n; i++) {
			char ss[1000];
			cin.getline(ss, 1000);
			string s(ss);
			s = s + ' ';
			int lst = 0;
			for(int j = 0; j < s.size(); j++) {
				if(s[j] == ' ') {
					string sub = s.substr(lst, j - lst);
					node tmp;
					tmp.op = sub[0];
					tmp.id = tran(sub.substr(1));
					tmp.to = j;
					process[i].push_back(tmp);
					lst = j + 1;
				}
			}
		}
		while(1) {
			bool flag = 0;
			int cnt = 0;
			for(int i = 0; i < n; i++) {
				if(p[i] == process[i].size()) {//這個程序到頭了
					cnt++;
					continue;
				}
				if(process[i][p[i]].op == 'S') {//傳送
					int to = process[i][p[i]].id;
					if(process[to][p[to]].op == 'R' && process[to][p[to]].id == i) {
						flag = 1;//如果接收的程序恰好能對上
						p[i]++;//更新p陣列即當前通訊的位置
						p[to]++;
					} else {
						//有可能已經死鎖 也有可能to還沒執行到
						continue;			
					}
				}
			}
			if(cnt == n) {//全部都到頭了
				break;
			} else if(!flag) {//如果這一輪一次對上的都沒有則死鎖
				sisuo = 1;
				break;
			}
		}
		cout << sisuo << endl;
	}
	return 0;
}