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


【題目描述】
  老師給了 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 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM