CCF 201903-4 100 points for messaging interface

table of Contents

Insert picture description here

Title

There are n processes communicating with each other, each process will only send and receive information in two operations, each process will have a task queue, the tasks in the queue must be executed one by one, let you judge whether it will deadlock

Ideas

First, each queue establishes a task queue, and the queue uses deque to
take out one task at a time

vector<deque<pair<char, int>>> processes;//全部进程的任务队列

Create two maps and store them when there is receiving information and sending information that cannot be matched temporarily

unordered_map<int, int> rec, send;//键为自身进程,值为目标进程

To maintain a task stack, first initialize n tasks to push them in, and then take them out in a loop until the stack is empty and end the loop. When the match is successful, the two processes that match successfully are pushed onto the stack (this method can handle the problem beyond the limit of the problem 8 or more tasks)

deque<int> taskque;
for (int i = 0; i < n; ++i)taskque.push_back(i);//初始化,把0到n-1条进程压入栈

As a result, there is no deadlock when both rec and send are empty

Code



#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <deque>
#include <unordered_map>
using namespace std;
int t, n;
vector<deque<pair<char, int>>> processes;//全部进程的任务队列
void execute() {
	unordered_map<int, int> rec, send;//键为自身进程,值为目标进程
	deque<int> taskque;
	for (int i = 0; i < n; ++i)taskque.push_back(i);//初始化,把0到n-1条进程压入栈
	while (!taskque.empty()) {
		int cur = taskque.front();
		taskque.pop_front();
		if (processes[cur].empty())continue;//进程内无任务跳过
		int num = processes[cur].front().second;
		if (processes[cur].front().first == 'S') {
			auto rp = rec.find(num);
			if (!rec.empty() && rp != rec.end() && rp->second == cur) {//如果目标进程正等待本进程的发送数据
				processes[num].pop_front();
				processes[cur].pop_front();//将自身进程和目标进程弹出一个任务
				taskque.push_front(num);
				taskque.push_front(cur);//将自身进程和目标进程压入栈
				rec.erase(num);
			}
			else 
				send.insert({ cur,num });
		}
		else {
			auto sp = send.find(num);
			if (!send.empty() && sp != send.end() && sp->second == cur) {
				processes[num].pop_front();
				processes[cur].pop_front();
				taskque.push_front(num);
				taskque.push_front(cur);
				send.erase(num);
			}
			else
				rec.insert({ cur,num });
		}
	}
	if (rec.empty() && send.empty())cout << '0' << endl;
	else cout << '1' << endl;
}



//#define DEBUG
int main()
{
#ifdef DEBUG
	fstream cin("input.txt");
#endif // DEBUG
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cin >> t >> n;
	cin.get();
	for (; t != 0; --t) {
		processes.resize(n);
		for (int i = 0; i < n; ++i) {
			stringstream strs;
			string temp;
			getline(cin, temp);
			strs << temp;
			int num; char c;
			while (strs >> c >> num)
				processes[i].push_back({ c,num });
		}
		execute();
		processes.clear();
	}
}

After reading it, you can still remember to like it

Test Data

//官方数据
2 3
R1 S1
R2 S0 R0 S2
S1 R1
R1
R2 S0 R0
S1 R1

//自己设的数据
1 5
S1 S1 S1 S1 R4 R4 R4 R4
R0 R0 R0 R0 S2 S2 S2 S2
R1 R1 R1 R1 S3 S3 S3 S3
R2 R2 R2 R2 S4 S4 S4 S4
R3 R3 R3 R3 S0 S0 S0 S0
//结果为0


Published 8 original articles · Likes6 · Visits 536

Guess you like

Origin blog.csdn.net/qq_41433566/article/details/105497974