CSP201903-4 訊息傳遞介面(模擬)
阿新 • • 發佈:2021-08-30
挺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; }