思路:
进程运行方式类似队列,顺序执行。匹配成功将这一对指令双双出队。继续运行,直到静止。若队列均为空,则无死锁;若存在队列不空,则有死锁。
标准的模拟题,没必要运用图论,递归等知识。若了解stringstream类,stoi等函数可极大简化编码。不过不用也可以,文末有一种较为麻烦的输入方式,不过速度会更快。
易错点:
进程编号能超过1位数,输入时要小心。
死锁判断时,若本队列已经为空,则一定要跳过,否则会报错。
#include<bits/stdc++.h>
using namespace std;
int T,n;
struct node{
char ch;
int op;
node(char a,int b):ch(a),op(b){};
};
inline int deadlock(queue<node> q[]){ //死锁处理
int flag1=2;//进程运行标记,无进展为1,有进展为2
while(flag1==2){
flag1=1;
for(int i=0;i<n;i++){
if(q[i].empty())continue;
node temp=q[i].front();
node cur=q[temp.op].front();
if(temp.ch!=cur.ch&&cur.op==i){
q[i].pop();
q[temp.op].pop();
flag1=2;
}
}
}
int flag2=0;//进程队列空标记 0为空 1为不空
for(int i=0;i<n;i++){
if(!q[i].empty()){
flag2=1;
}
}
return flag2;
}
int main(){
ios::sync_with_stdio(false);
cin>>T>>n;
cin.get();
for(int i=0;i<T;i++){
queue<node> q[n];
for(int j=0;j<n;j++){
//输入
string str;
getline(cin,str);
stringstream ss;
string s;
ss<<str;
while(ss>>s){
q[j].push(node(s[0],stoi(s.substr(1))));
}
//输入结束
}
//处理&输出
cout<<deadlock(q)<<endl;
}
return 0;
}
样例:
3 2
R1 S1
S0 R0
R1 S1
R0 S0
R1 R1 R1 R1 R1 R1 R1 R1
S0 S0 S0 S0 S0 S0 S0 S0
3 2
R1 S1
R0 R0
R1 S1
R0 S0
R1 R1 R1 R1 R1 R1 R1 R1
S0 S0 S0 S0 S0 S0 S0 S0
2 3
R1 S1
R2 S0 R0 S2
S1 R1
R1
R2 S0 R0
S1 R1
麻烦但更快的输入方式:
//输入
string str;
getline(cin,str);
int beg=0,s,ch,num;
while(str.find(' ',beg)!=-1){
s=str.find(' ',beg);
ch=str[beg++];
num=0;
for(int k=beg;k<s;k++){
num=num*10+str[k]-'0';
}
q[j].push(node(ch,num));
beg=s+1;
}
ch=str[beg++];
num=0;
for(int k=beg;k<str.size();k++){
num=num*10+str[k]-'0';
}
q[j].push(node(ch,num));
//输入结束