题目思路:
终于碰见个正常的第四题,这个题只需要简单模拟一下操作系统的进程状态就好了。
首先我们定义,一个进程有 运行,阻塞,就绪三种状态。
数据结构:
C【i】【j】 :为结构体变量,存i号进程的第j条指令,tp存R or S ,id存后边的数。
就绪队列queue<int>q :待执行下一条指令的进程编号。
阻塞数组block[x] :同C为结构体变量,tp和id分别就是他执行到哪一条指令被阻塞了。
idx【x】 :x号进程正在执行第几号指令
all【x】 :x号进程一共有多少条指令。
模拟过程:
先把全部进程扔到就绪队列,将block数组清空。并且初始化idx为1,表示正在执行第一号指令, 让后定义R为1,S为2。
取出队首,判断是否可以解除某条进程的阻塞状态,R解除S,S解除R。
1. 如果解除不了某个进程的阻塞状态的话,设置他为阻塞,并且block赋值为他的阻塞指令。
2. 如果解除了阻塞状态,那么指令计数数组idx加一,如果还有指令要执行。清空block,塞回就绪队列。
最后判断每一个进程的 idx数组值 是否比 all数组的 大就好了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e4+5;
queue<int>q;
struct node{
int tp,id;
node(){}
node(int a,int b){
tp = a;id = b;
}
}C[MAXN][10],block[MAXN];
int all[MAXN],idx[MAXN];
int t,n;
void input()
{
while(q.size())q.pop();
memset(all,0,sizeof(all));
string s;
for(int j=0;j<n;j++){
idx[j] = 1;
q.push(j);
block[j].tp = 0,block[j].id = 0;
getline(cin,s);
int len = s.size();
int f = 0,cnt = 0;
for(int i=0;i<=len;i++){
if(s[i] == 'R')f = 1;
if(s[i] == 'S')f = 2;
if(s[i]>='0' && s[i]<='9'){
cnt = cnt*10 + s[i]-'0';
}
if(i == len||s[i] == ' '){
C[j][ (++all[j]) ].tp = f;
C[j][ all[j] ].id = cnt;
cnt = 0;
}
}
}
}
void fun(int x)
{
idx[x]++;
if(idx[x]<=all[x]) {
q.push(x);
block[x].tp = block[x].id = 0;
}
}
int main()
{
cin>>t>>n;
getchar();
while(t--)
{
input();
while(q.size()){
int x = q.front();
q.pop();
int now_idx = idx[x];
int len = all[x];
int op_tp = C[x][now_idx].tp;
int op_id = C[x][now_idx].id;
if(block[op_id].tp == 3-op_tp && block[op_id].id == x){
fun(x);
fun(op_id);
}
else{
block[x].tp = op_tp;
block[x].id = op_id;
}
}
bool f = 0;
for(int i=0;i<n;i++){
//cout<<i<<" : "<<block[i].tp<<" + "<<idx[i]<<endl;
if(idx[i]<=all[i] )f = 1;
}
cout<<f<<endl;
}
}
/*
3 2
R1 S1
S0 R0
R1 S1
R0 S0
R1 R1 R1 R1 S1 S1 S1 S1
S0 S0 S0 S0 R0 R0 R0 R0
2 3
R1 S1
R2 S0 R0 S2
S1 R1
R1
R2 S0 R0
S1 R1
*/