用stringstream处理输入会很方便,考试的时候我记得也是这个思路。但是我考试的时候把队列数组开在了for循环里,这样会爆栈。
所以一定要注意:大数组一定一定要设为全局变量!!!不要开在函数里!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<sstream>
#include<stack>
using namespace std;
struct node
{
char c;
int place;
node(char c_, int place_) {
c = c_;
place = place_;
}
};
//队列数组,每个队列下标表示是几号进程,用来存放执行的命令
queue<node> q[10005];
int n;
void run()//模拟进程接受,发送信号
{
int cnt = 0;
//从0号进程到n号进程,队列中有消去则flag_设为1,重复执行,无消去则结束模拟过程
while (cnt<n) {
int flag = 0;
for (int k1 = 0; k1 < n; k1++) {
if (!q[k1].empty()) {
//临时node存放队列首元素
node t_n = q[k1].front();
if (t_n.c == 'S' && !q[t_n.place].empty()) {
node t_n2 = q[t_n.place].front();
//当目标进程号的执行命令对应时,pop队列首元素
if (t_n2.c == 'R'&&t_n2.place == k1) {
q[k1].pop();
if (q[k1].empty())
cnt++;
q[t_n.place].pop();
if (q[t_n.place].empty())
cnt++;
flag = 1;
}
//S与S对应且进程号相同,产生死锁,结束函数
}
else if (t_n.c == 'R' && !q[t_n.place].empty()) {
node t_n2 = q[t_n.place].front();
if (t_n2.c == 'S'&&t_n2.place == k1) {
q[k1].pop();
if (q[k1].empty())
cnt++;
q[t_n.place].pop();
if (q[t_n.place].empty())
cnt++;
flag = 1;
}
}
}
}
if (!flag)
return;
}
}
int main()
{
int t;
int i, j;
cin >> t >> n;
getchar();
for (i = 0; i < t; i++) {
int e;
for (e = 0; e < n; e++) { //清空队列
while (!q[e].empty()) {
q[e].pop();
}
}
for (j = 0; j < n; j++) {
string s;
getline(cin, s); //读取一行
stringstream ss(s);
string str;
while (ss >> str) {
q[j].push(node(str[0], atoi(str.substr(1).c_str())));
}
}
run();//模拟进程接受,发送信号
int flag = 0;
//当所有队列为空说明无死锁,否则有死锁
for (int k = 0; k < n; k++) {
if (!q[k].empty()) {
flag = 1;
break;
}
}
cout << flag << endl;
}
return 0;
}