ccf 201903-4
Posted shiliuxinya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ccf 201903-4相关的知识,希望对你有一定的参考价值。
题解:不能任意匹配,只能是队头和队头的匹配。匹配的条件是:操作类型相反且互为操作进程数
①用队列数组存储数据,每次算完一组数据之后记得清空队列
②用getline获取一行字符,包括字符串。
先输入T,n然后换行的话,getline会把T、n的换行符当成输入,就会出错,所以在scanf("%d %d,&T,&n)之后多写了一个getline()来吃掉换行符,防止被原本的getline()识别到
③跳出循环的情况:
count:无法匹配的队头个数 empty:队列为空的个数
(1)count==n,如果一轮匹配中,所有的队头都无法匹配,则死锁,跳出循环 (这里把空队列也当做无法匹配的情况)
(2)empty==n,所有队列均为空,匹配完成,跳出循环
④每次找到相匹配的两个数时,将这两个数据弹出对列,然后判断是否队空,队空则empty++,empty==n时即可break
⑤注意:数字不是只用一位数表达! n<=10000, 所以进程的编号也是<=10000,而不是<=10,不是个位数!
#include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <queue> #include <ctype.h> #define MAX 10005 using namespace std; typedef struct Node{ char type; //R 、S int num; //该操作的所匹配的进程编号 }Node; queue<Node> q[MAX]; //队列数组 int main(){ int T,n; char type1,type2; int k,count,flag,empty; string str; string change; char type; int num; scanf("%d %d",&T,&n); getline(cin,change); for(int i=0;i<T;i++){ for(int j=0;j<n;j++){ //要清空队列,否则会出错,因为count==n时退出的时候队列还有元素 while(!q[j].empty()) //队列没有clear() q[j].pop(); } for(int j=0;j<n;j++) { getline(cin,str); num=0; int len=str.size(); for(int k=0; k<len;k++){ //数字不是只有1位 ! 数字有很多位!要计算! if(str[k]==‘S‘ || str[k]==‘R‘) type=str[k]; else if(isdigit(str[k])) num = num*10 + (str[k]-‘0‘); else { Node node; node.type=type; node.num=num; q[j].push(node); num=0; } if(k==len-1){ Node node; node.type=type; node.num=num; q[j].push(node); num=0; } } } flag=1; empty=0; //队列为空的进程数 count=0; //count要初始化 否则会出错 while(1){ //队列全为空时跳出 if(count==n){ //不能匹配的进程数=所有的进程数 flag=1; //反锁 break; } if(empty==n){ flag=0; break; } count=0; //不能匹配的进程数 for(int p=0;p<n;p++){ //一轮 if(q[p].empty()){ //进程p为空则跳过,算作不能匹配数 count++; continue; } Node node1=q[p].front(); //取第p个进程的队头 char type1=node1.type; int num1=node1.num; //操作的进程编号 if(q[num1].empty()){ //进程num1为空跳过,count++ count++; continue; } Node node2=q[num1].front(); //取第num1个进程的队头 char type2=node2.type; int num2=node2.num; if(type1 !=type2 && num2 == p){ //操作类型相反,且互为操作数 q[p].pop(); q[num1].pop(); if(q[p].empty()) empty++; //判断是否队空 if(q[num1].empty()) empty++; //所有队列都空时跳出循环 } else count++; } } if(flag) printf("1 "); else printf("0 "); } return 0; }
以上是关于ccf 201903-4的主要内容,如果未能解决你的问题,请参考以下文章