【题目描述】
  老师给了 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 }