题目略
- 思路:对于任何一个时候,只看每个进程的第一条指令就可以判断是否会锁死了。如果有一对进程的第一条指令配对成功,那么就执行这两条指令(出队列);相反所有进程的第一条指令都配对失败,那么就已经死锁了。然后每次都这么判断就好了。
- 整体框架如下
flag=1;
while(flag){
flag = 0;
if(有配对成功) flag=1;
}
output(flag);
- 数据结构方面,我是用一个队列数组来模拟n个进程,每个进程对应一个队列
- 我遇到的坑:
- 输入方面,fgets是会读取\n,即换行符的,我就一直认为每一行的末尾一定是\n,结果一直90分,在测试了多次之后(心累),结果应该是因为最后一行没有\n吧,就是最后一行数据应该没有换行符。处理一下就满分了。
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <string>
#include <string.h>
using namespace std;
const int MAX_N = 10000 + 100;
const int MAX_LINE = 80;//(1+5+1)*8 经测试,这里居然随便写?我写长度为1照样通过100分
int T,n;
struct Cmd{
int op,to;
public:
Cmd(char* str){
if(str[0]=='R') op = 0;
else op = 1;
to = atoi(str+1);
// to = 0;
// for(int i=1; str[i]; i++){
// to *= 10;
// to += str[i]-'0';
// }
// to = to%n;
}
};
queue<Cmd> q[MAX_N];
char str[MAX_LINE];
char temp[100];
int main(int argc, char* argv[])
{
if(argc==2){
char* filename = argv[1];
freopen(filename, "r", stdin);
}
scanf("%d%d", &T,&n);
getchar();
while(T--){
for(int i=0; i<n; i++)
while(!q[i].empty()) q[i].pop();
for(int i=0; i<n; i++){
//gets(str);
fgets(str, sizeof(str), stdin);
//scanf("%s", str);
//int len = strlen(str);
//str[len] = '\n';
//str[++len] = '\0';
int k = 0;
for(int j=0; str[j]; j++){
if(!isalpha(str[j]) && !isdigit(str[j])){
temp[k] = '\0';
q[i].push(Cmd(temp));
k=0;
}else{
temp[k++] = str[j];
}
}
int len = strlen(str);
if(isalpha(str[len-1]) || isdigit(str[len-1])){
temp[k] = '\0';
q[i].push(Cmd(temp));
}
}
int isChange = 1;
while(isChange){
isChange = 0;
for(int i=0; i<n; i++){
if(!q[i].empty()){
Cmd u = q[i].front();
if(q[u.to].empty()) break;//此时已经可以判断是死锁状态了
Cmd v = q[u.to].front();
if(u.op^v.op && v.to==i){
isChange = 1;
q[i].pop(); q[u.to].pop();
//break; 如果break的话,会重复判断无用的,影响运行时间
}
}
}
}
int i;
for(i=0; i<n; i++){
if(!q[i].empty()) break;
}
if(i==n) puts("0");
else puts("1");
}
return 0;
}