【題目描述】
老師給了 T 份 MPI 的樣例代碼,每份代碼都實現了 n 個進程通信。這些進程標號 從 0 到 n − 1,每個進程會順序執行自己的收發指令,如:“S x”,“R x”。“S x”表示向 x 號進程發送數據,“R x”表示從 x 號進程接收數據。每一對收發命令必須匹配執行才 能生效,否則會“死鎖”。
舉個例子,x 號進程先執行發送命令“S y”,y 號進程必. 須. 執行接送命令“R x”,這 一對命令才執行成功。否則 x 號進程會一直等待 y 號進程執行對應的接收命令。反之, 若 y 號進程先執行接收命令“R x”,則會一直等待 x 號進程執行發送命令“S y”,若 x 號進程一直未執行發送命令“S y”,則 y 號進程會一直等待 x 號進程執行對應的發送 命令。上述這樣發送接收命令不匹配的情況都會造成整個程序出現“死鎖”。另外,x 號進程不會執行“S x”或“R x”,即不會從自己的進程發消息.
現在老師請你判斷每份樣例代碼是否會出現“死鎖”的情況。每個進程的指令最少 有 1 條,最多有 8 條,這些指令按順序執行,即第一條執行完畢,才能執行第二條,依 次到最后一條。
老師給了 T 份 MPI 的樣例代碼,每份代碼都實現了 n 個進程通信。這些進程標號 從 0 到 n − 1,每個進程會順序執行自己的收發指令,如:“S x”,“R x”。“S x”表示向 x 號進程發送數據,“R x”表示從 x 號進程接收數據。每一對收發命令必須匹配執行才 能生效,否則會“死鎖”。
舉個例子,x 號進程先執行發送命令“S y”,y 號進程必. 須. 執行接送命令“R x”,這 一對命令才執行成功。否則 x 號進程會一直等待 y 號進程執行對應的接收命令。反之, 若 y 號進程先執行接收命令“R x”,則會一直等待 x 號進程執行發送命令“S y”,若 x 號進程一直未執行發送命令“S y”,則 y 號進程會一直等待 x 號進程執行對應的發送 命令。上述這樣發送接收命令不匹配的情況都會造成整個程序出現“死鎖”。另外,x 號進程不會執行“S x”或“R x”,即不會從自己的進程發消息.
現在老師請你判斷每份樣例代碼是否會出現“死鎖”的情況。每個進程的指令最少 有 1 條,最多有 8 條,這些指令按順序執行,即第一條執行完畢,才能執行第二條,依 次到最后一條。
【輸入格式】
從標准輸入讀入數據。 輸入第一行兩個正整數 T, n,表示有 T 份樣例代碼,實現了 n 個進程通信。 接下來有 T × n 行,每行有若干個(1 − 8 個)字符串,相鄰之間有一個空格隔開
(比如,“S1”表示向 1 號進程發送消息,“R1”表示從 1 號進程接收消息。細節請 參考樣例。)
【輸出格式】
輸出到標准輸出。輸出共 T 行,每行一個數字,表示對應樣例代碼是否出現“死鎖”的情況。1 表示 死鎖,0 表示不死鎖
。
核💗: 構建一個消息隊列: 在隊列的是每一個人的第一個元素
我們要維護這個隊列,逐個彈出x,如前面有可以配對的y,消去x. 同時更新x,y第一個元素進隊
若彈出出無法消去,記錄[ s[x]=y 表示x第一個元素是Sy; r[x]=y表示x第一個元素是Ry
ps: 我其他ccf代碼也很簡潔易懂哦...做題重要的是想清楚,邏輯清晰
希望我的代碼可以幫助大家,祝大家取得好成績.
也祝福我最喜歡的女孩子-mt取得好成績...加油...最努力的你!
代碼:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef vector <string> vs; 4 const int N=1e4+7; 5 struct node { // 消息類型 6 int x,y; // x->y flag=1 是S 7 bool flag; 8 }; 9 int s[N],r[N]; // S[x]=y 表示x 第一個消息是Sy 10 node msg[N][10]; int num[N]; // msg 以倒序方式存儲每一個人所有消息 11 // num[i] 表示第i個人消息數量 12 queue <node> q; // 建立消息隊列 13 int n; 14 vs split (string str, const char flag=' ') { // 分割字符串 15 istringstream iss(str); 16 vs ans; 17 while (getline(iss,str,flag)) 18 if (str.size()) 19 ans.push_back(str); 20 return ans; 21 } 22 int to_int (string str) { // string->int 23 int ans=0; 24 for (int i=0;i<str.size();i++) 25 ans=ans*10+str[i]-'0'; 26 return ans; 27 } 28 void get_in (int k) { // 所有人的第一個消息進隊列 29 if (num[k]) { // 沒有元素不進行任何操作 30 // 編程還重要的是構造統一的接口,簡化代碼 31 q.push(msg[k][num[k]]); 32 num[k]--; 33 } 34 } 35 int main () 36 { 37 int T; cin>>T>>n; getchar(); 38 while (T--) { 39 memset (s,-1,sizeof(s));// 初始化很重要 40 memset (r,-1,sizeof(r)); 41 memset (msg,0,sizeof(msg)); 42 memset (num,0,sizeof(num)); 43 for (int i=0;i<n;i++) { 44 string str; getline(cin,str); 45 vs sv=split(str); 46 num[i]=sv.size(); 47 for (int j=0;j<sv.size();j++) { // 對消息的處理 48 int k=num[i]-j; 49 msg[i][k].x=i; 50 msg[i][k].y=to_int(sv[j].substr(1)); 51 if (sv[j][0]=='S') msg[i][k].flag=1; 52 } 53 } 54 for (int i=0;i<n;i++) get_in(i); // 開始所有人的第一個進入隊列 55 int sum=0; 56 while (!q.empty()) { 57 node tmp=q.front(); q.pop(); 58 bool isok=0; 59 int x=tmp.x,y=tmp.y; 60 if (tmp.flag) { // 若這個消息此時有對應 則消去 對應是指[ s[x]=y; r[y]=x; ] 61 if (r[y]==x) { isok=1; r[y]=-1; get_in(x); get_in(y); } // 消去的時候兩人下一個消息進入隊列 62 else s[x]=y;// 不能消去 更新 63 } 64 else { 65 if (s[y]==x) {isok=1; s[y]=-1; get_in(x); get_in(y); } 66 else r[x]=y; 67 } 68 if (isok) sum++; // sum 表示為被消去的消息數量 69 else sum--; 70 } 71 if (sum==0) cout<<"0\n"; 72 else cout<<"1\n"; 73 } 74 return 0; 75 }

