【题目描述】
老师给了 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 }
抓住青春的尾巴。。。