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\n",flag);
    }
} 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM