这个题感觉有失水准…有点过于简单了
我看了看网上的其他代码,好像都是在模拟通信,实际上没有这么麻烦。这道题实际上就是队列的应用,每一个设备代表一个队列,要保证不死锁,那么每次循环一遍所有的设备,必须要处理一对信息。
因此需要两个bool值,一个代表全部队列是否为空,一个代表本次循环是否处理了信息,如果队列为空说明没有死锁,如果一次循坏未处理信息那么代表存在死锁。
实现的时候,每遍历到一个R,那么就去尝试找对应设备的S,遍历到S就去找R,如果没有死锁,那么遍历一个循环肯定能找到一对RS
具体实现的时候,用标准库实现的队列超时了…大概是因为clear()之类的操作太耗时间了,我用标准库最后只拿到了90分,然后手撸了一个固定数组大小的队列,就通过了,感觉第四题比第三题要简单多了…就是思路的问题。
哦对了这个题可能还有一个难点就是如何接受字符串,可以看一下我使用的方法,效率非常高,不用多余的处理,直接接受到各自的RS和id号
#include<cstdio>
#include<queue>
#include <cstring>
using namespace std;
struct mpi{
char c;
int to;
// mpi(char _c,int _id):c(_c),toid(_id){}
};
int T,n;
void clear(queue<mpi>& q) {//于标准库配套的方法,最快的一种
queue<mpi> empty;
swap(empty, q);
}
//queue<mpi> qs[10001];
struct queue{//这里用标准库会超时,只能拿90分
int right=0;
int left=0;
mpi content[50];
void push(mpi &c){
content[right++] = c;
}
mpi front(){
return content[left];
}
void pop(){
left++;
}
bool empty(){
return left == right;
}
void clear(){
left = 0;right=0;
}
}qs[10001];
void solve(){
bool allemp = false;
while(true){
allemp = true;
bool doop = false;
for(int i = 0;i<n;i++)
{
if(!qs[i].empty())
{
allemp=false;
}else{
continue;
}
mpi tmp = qs[i].front();
if(tmp.c=='R')
{
mpi from = qs[tmp.to].front();
if(from.c == 'S' && from.to == i)
{
qs[i].pop();
qs[tmp.to].pop();
doop = true;
i = -1;
}
}else{
mpi from = qs[tmp.to].front();
if(from.c == 'R' && from.to == i)
{
qs[i].pop();
qs[tmp.to].pop();
doop = true;
i = -1;
}
}
}
if(allemp)
{
printf("0\n");
break;
}
if(!doop)
{
printf("1\n");
break;
}
}
}
int main() {
scanf("%d%d%*c",&T,&n);
char code[4000];
for(int i = 0;i<T;i++)
{
int len = -1;
for(int j = 0;j<n;j++)
{
// while(!qs[j].empty()){qs[j].pop();}
// clear(qs[j]);
qs[j].clear();
fgets(code,4000,stdin);
len = strlen(code)-1;
int iter = 0;
for(int k = 0;k<len;)
{
mpi cur;
sscanf(code+k, "%c%d%*c%n", &cur.c, &cur.to, &iter);
k+=iter;
qs[j].push(cur);
}
}
solve();
}
return 0;
}
2019年9月6日更新,二刷,提供了逻辑相同,但更简单的实现,确实二刷的时候感觉不一样了…思路清楚了不少,另外还提供了直接接受字符串的一个方法,理论上是绝对没有问题的,但是会超时,我不知道为什么,会直接超时到零分…注释掉换了之前的实现后可以了…奇了怪了…
#include <bits/stdc++.h>
using namespace std;
struct info{
char type;
int from;
int to;
};
struct queue{
info is[10];
int start=0;
int end=0;
void push(info &i){
is[end] = i;
end++;
}
info front(){
return is[start];
}
void pop(){
start++;
}
bool empty(){
return start == end;
}
void clear(){
start = 0;
end = 0;
}
int size(){
return end-start;
}
}q[10001];
int main(){
int T,n;
scanf("%d%d%*c",&T,&n);
while(T--)
{
for(int i = 0;i<n;i++)
{
q[i].clear();
char code[4000];
int len;
fgets(code,4000,stdin);//先读取一行再处理!否则会超时!原因未知!
len = strlen(code)-1;
int iter = 0;
for(int k = 0;k<len;)
{
info cur;
cur.from = i;
sscanf(code+k, "%c%d%*c%n", &cur.type, &cur.to, &iter);
k+=iter;
q[i].push(cur);
}
//原来的实现方法
// char split = ' ';
// while(split != '\n'){
// info tmp;
// tmp.from = i;
// scanf("%c%d%c",&tmp.type,&tmp.to,&split);
// q[i].push(tmp);
// }
}
int size = q[0].size();
bool op=true;
while(op)
{
op = false;
for(int i = 0;i<n;i++)
{
if(q[i].empty())
{
continue;
}
info cur = q[i].front();
if(q[cur.to].empty())
{
continue;
}
if(q[cur.to].front().type != cur.type && q[cur.to].front().to == cur.from)
{
op = true;
q[i].pop();
q[cur.to].pop();
break;
}
}
}
bool emp = true;
for(int i = 0;i<n;i++)
{
if(!q[i].empty())
{
emp = false;
break;
}
}
if(emp)
{
printf("0\n");
}else{
printf("1\n");
}
}
return 0;
}
/**
*/