题意:
有 t 个测试案例,每个测试案例有 n 个进程,每个进程一行,编号为 0~n-1。有两种操作 Rx(从 x 进程读取消息) 和 Sx(向 x 进程发出消息)。0号进程执行R1 ,则1号进程执行 S0 才能与0号进程匹配,否则会产生 ‘死锁’。不会从自己的进程收发消息。判断是否有死锁产生。
用n个队列进行模拟
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
struct node
{
char s; //操作
int x; //进程号
node(char a,int b)
{
s = a;
x = b;
}
};
queue<node> q[10010];
//队列数组,下标对应进程号,存放执行的命令
int t,n;
void prime()
{
int flag = 1; //判断是否有消去的命令
//从0号进程到n-1号进程,队列中有消去则flag为1,重复执行,无消去则结束模拟过程
while(flag)
{
flag = 0;
for(int i=0; i<n; i++)
{
if(!q[i].empty())
{
node w = q[i].front(); //存放队列首元素
if(q[w.x].empty())
return ;
node h = q[w.x].front();//对应进程
if(w.s=='S')
{
//当操作相互对应时,消去操作
if(h.s=='R' && h.x==i)
{
q[i].pop();
q[w.x].pop();
flag = 1;
}
// 同种操作,产生死锁,进程结束
else if(h.s=='S' && h.x==i)
return ;
}
else if(w.s=='R')
{
if(h.s=='S' && h.x==i)
{
q[i].pop();
q[w.x].pop();
flag = 1;
}
else if(h.s=='R' && h.x==i)
return ;
}
}
}
}
}
int main()
{
cin>>t>>n;
getchar();
for(int i=0; i<t; i++)
{
string s;
char str;
int x;
for(int j=0; j<n ;j++)
{
while(!q[j].empty())
q[j].pop();
}
for(int j=0; j<n ;j++)
{
getline(cin,s); // 读入一行
int k = 0;
while(k<s.size())
{
if(s[k]=='R' || s[k]=='S')
{
str = s[k];
k++;
x = 0;
while(s[k]>='0' && s[k]<='9')
{
x = x*10+s[k]-'0';
k++;
}
q[j].push(node(str,x));
}
k++;
}
}
prime();
bool flag = false;
//当队列不为空时,有死锁产生
for(int j=0; j<n; j++)
if(!q[j].empty())
flag = true;
cout<<flag<<endl;
}
return 0;
}