ccf csp—201903-4 消息传递接口

题目略

  • 思路:对于任何一个时候,只看每个进程的第一条指令就可以判断是否会锁死了。如果有一对进程的第一条指令配对成功,那么就执行这两条指令(出队列);相反所有进程的第一条指令都配对失败,那么就已经死锁了。然后每次都这么判断就好了。
  • 整体框架如下
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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值