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;
}
原文地址:https://www.cnblogs.com/shiliuxinya/p/12189155.html