zoukankan      html  css  js  c++  java
  • ccf——201903-4 消息传递接口

    参考

    题目解读:

    老师给了T份样例,有n个进程,这n个进程之间可以receive接收和send发送消息(如R1,S2....)。R,S即接收和发送的进程号要对应起来,例如R1必须与S0配对。

    当开始时,初始所有的进程为准备就绪的状态,然后开始从第一个进程的第一个消息A开始,如果A消息要和第x号进程进行R 或 S,就看X号进程队列的头部B是否能和A配对,如果能配对,就继续第一个进程的下一个消息;如果不能,就先处理X号进程,看B要和哪一个进程配对,配对好了就继续X号里的下一个消息,直到能找到和A配对的消息,这是一个递归的过程。当然,在这过程中,如果发现有进程处于一直等待状态,或配对过程中发现某一方进程已经为空,这份样例的代码就处于“锁死”了。

    知识点:

    queue

    #include<queue>           //头文件
    
    queue<int> test;          //初始化一个int型的队列名为test
    
    test.empty() ;                //查看队列是否为空
    test.size();                //返回队列大小
    test.front();                //返回队列下一个元素
    test.back();                // 返回队列最后一个元素
    test.push();                 //添加一个元素
    test.pop();                    //删除队列下一个元素
    test.emplace();                //构造和插入元素
    test.swap();                //交换内容 

    istringstream:

    istringstream类用于执行C++风格的串流的输入操作、

    这里用于将字符串从空格处分开

    atoi():
    C库函数,将数值型字符转化为数值

    c_str()

    通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式,这样就可以在C库函数里使用了

    代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<sstream>
    #include<queue>
    using namespace std;
    const int MAXN=10005;
    //每个消息的结构 
    struct Mes{ 
        char flag;//接收消息
        int target;//目标进程 
    }; 
    //进程 
    struct Pro{
        queue<Mes> task;
    }; 
    
    Pro pro[MAXN];//进程数组
    int wait[MAXN];//进程状态
    int receiveM(int from,int to);
    int sendM(int from,int to);
    
    int exe(int now)
    {
        if(wait[now]==1) return -1;//判断当前进程是否处于等待
        if(pro[now].task.empty()) return 0;//队列为空,则表示该进程消息已经处理完毕
        Mes cur=pro[now].task.front();
        if(cur.flag=='R')
        {
            wait[now]=1;//现在该进程在进行任务,其他消息只能等待
            if(receiveM(now,cur.target)==-1) return -1;
            
            //消息接收成功
            pro[now].task.pop();//消息处理成功,从消息队列里移除
             wait[now]=0;//消息处理完毕,进程继续准备
             if(exe(now)==-1) return -1;//处理下一个消息
             return 0; 
        } else if(cur.flag=='S')
        {
            wait[now]=1;
            if(sendM(now,cur.target)==-1) return -1;
            
            //成功配对
            wait[now]=0;
            pro[now].task.pop();
            if(exe(now)==-1) return -1;
            return 0;    
        }
    }
    
    int receiveM(int from,int to)
    {
        if(wait[to]==1) return -1; 
        if(pro[to].task.empty()) return -1;//如果该进程已经没有消息了,接不会执行 
        Mes cur=pro[to].task.front();
        if(cur.flag=='R')
        {
            wait[to]=1;
            if(receiveM(to,cur.target)==-1) return -1;//递归处理下一个消息
            
            wait[to]=0;
            pro[to].task.pop();
            if(receiveM(from,to)==0) return 0;//递归判断之前的消息是否可以处理
            return -1;
             
        }
        else if(cur.flag=='S')
        {
            if(from==cur.target){
                pro[to].task.pop();
                return 0;
            
            }
            //不能配对成功
            wait[to] =1;
            if(sendM(to,cur.target)==-1) return -1;
            
            wait[to]=0;
            pro[to].task.pop();
            if(receiveM(from,to)==0) return 0;
            return -1; 
    }    
    }
     
    int sendM(int from,int to)
    {
        if(wait[to]==1) return -1;
        if(pro[to].task.empty()) return -1;
        Mes cur=pro[to].task.front();
        if(cur.flag=='R')
        {
            if(from==cur.target)
            {
                pro[to].task.pop();
                return 0;
            }
            
            wait[to]=1;
            if(receiveM(to,cur.target)==-1) return -1;
            
            wait[to]=0;
            pro[to].task.pop();
            if(sendM(from,to)==0) return 0;
            return -1;
            
        }
        else if(cur.flag=='S')
        {
            wait[to]=1;
            if(sendM(to,cur.target)==-1) return -1;
            wait[to]=0;
            pro[to].task.pop();
            if(sendM(from,to)==0) return 0;
            return -1;
        }
    } 
    
    int T,n;
    int main()
    {
        scanf("%d %d",&T,&n);
        getchar();//回车 
        for(int i=0;i<T;i++)
        {
            memset(wait,0,sizeof(wait));//初始化进程状态
            
            for(int j=0;j<n;j++)
            {
                //初始化每个进程的消息队列 
                while(!pro[j].task.empty())
                pro[j].task.pop();
             } 
             
             for(int j=0;j<n;j++)
             {
                 //处理输入 
                 string line;
                 getline(cin,line);
                 istringstream ss(line);
                 string tmp;
                 while(ss>>tmp){
                     Mes mes;
                     mes.flag=tmp[0];//获取R,S
                    mes.target=atoi(tmp.c_str()+1);//获取目标进程 
                    pro[j].task.push(mes); //加入消息队列 
                 }
              } 
              int flag=0;
              for(int j=0;j<n;j++)
              {
                  if(!pro[j].task.empty())
                  {
                      if(exe(j)==-1){
                          //锁死
                          flag=1;
                          break; 
                      }
                  }
              } 
              printf("%d
    ",flag);
        }
    } 
  • 相关阅读:
    产品流程关键点分析
    Hadoop分布式文件系统(HDFS)设计
    什么是产品经理
    转:互联网产品开发流程
    如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1
    mobile app 与server通信的四种方式
    Android: Client-Server communication
    Android: Client-Server communication by JSON
    Samba 源码解析之SMBclient命令流
    Samba 源码解析之内存管理
  • 原文地址:https://www.cnblogs.com/ellen-mylife/p/11120640.html
Copyright © 2011-2022 走看看