CCF 201903 4 訊息傳遞介面

2021-09-25 17:13:44 字數 2918 閱讀 7410

分析:這次的出題老師貌似特別擅長作業系統,第三道才考磁碟陣列,第四道立刻又來了道死鎖。本著預設第四道是圖論或者dp的想法,看完題目覺得可能不會像表面那麼簡單,但是做完發現還真的只是道模擬題。

比較坑的是開始做題一直提交二十分,提示錯誤。仔細重新讀題若干遍,又檢查**若干遍,不管如何改都是二十分。最後看了下別人滿分的**,按照他的思路寫了下,提交四十分,遂又檢查整個邏輯,確認邏輯完全一致後,提交前順手刪掉了禁止同步的語句,提交就ac了。再提交下原來的**,同樣可以ac,原來浪費這麼久時間查錯竟然只是禁用同步後同時使用了getchar和cin造成輸出結果有所差異的。下面進入主題:

第一點需要注意的是,在用cin讀取了t和n之後,直接用getline讀下面的行會讀到回車字元,一般情況下需要加上getchar()去掉回車字元,但是如果要加上禁用同步的語句後便不能使用getchar()了,可以使用cin.get()代替。

首先,確定儲存,對於每組程式,會有n行,每行不超過8條指令,所以可以用string型別的二維陣列儲存。同時,再讀入每行後,需要按空格分割下讀入的命令。

const int maxn = 11005;

string task[maxn][9];

string s, str;

res = 0;

for (int i = 0; i < n; i++)

else

p++;

}task[i][q] = str;

str.clear();

res += q + 1;

}

然後就是逐行遍歷指令集,看看有沒有配對的指令。對於一條string型別的指令,比如0號程序的r1,需要1號程序的s0來配對。這裡先介紹一種方法就是當指令的第乙個字元不等,且後面對應的數字配對時指令才配對。這裡要注意,程序的編號可能不止一位數,所以不能直接取字串的第二位作為與之通訊的程序編號,自己封裝乙個函式即可。

int findnum(string &s) 

return ans;

}

鑑於程序匹配的函式較為簡單,直接給出再進行解釋。

bool match(int cur)
cur-當前遍歷到的程序編號,pos[cur]當前程序遍歷到的指令下標,s就是當前程序遍歷到的指令了。p-需要尋找與之配對程序的編號。如果想要配對的程序p正在執行的指令不是在等待cur程序的訊息或者兩個程序收發訊息方向一致(r-r,s-s)則不匹配,反之則匹配,指向兩個程序正在執行指令下標的指標++。為了不從頭多次遍歷程序,當與cur配對成功的程序p小於cur,說明已經遍歷過的程序還在往下指向,便需要繼續執行p程序。總的**如下:

方法一:

#include #include #include #include #include using namespace std;

int t, n;

const int maxn = 11005;

string task[maxn][9];

int pos[maxn];//程序執行到的位置

int res = 0;

int findnum(string &s)

return ans;

}bool match(int cur)

int main()

else

p++;

}task[i][q] = str;

str.clear();

res += q + 1;

} for (int i = 0; i < n; i++)

if (res) cout << "1" << endl;

else

for (int i = 0; i < n; i++)

memset(pos, 0, sizeof pos);

} return 0;

}

注意:如果二維陣列的maxn設為10005時,只能得80分,不知為啥會越界導致執行錯誤,所以開大點就能得100分了。 

方法二:

方法二則是直接用佇列模擬該過程,不同的是處理s,r時,將r對映為0,s對映為1,直接將字元x(r or s) 減去'0'即可得到對映後的數。奇怪的是,這裡的佇列陣列開10005並不會執行錯誤,可以直接ac。

#include #include #include #include #include #include using namespace std;

int t, n;

const int maxn = 10005;

struct node ;

queuequ[maxn];

int findnum(string &s)

return ans;

}int main() );

str.clear();

}else

p++;

}qu[i].push();

str.clear();

} int cnt;

while (1)

if (!cnt) break;//一趟遍歷沒有減少指令數

} bool flag = true;

for (int i = 0; i < n; i++)

} if (flag) cout << "0" << endl;

for (int i = 0; i < n; i++)

} }return 0;

}

CCF 201903 4訊息傳遞介面(佇列)

我的個人部落格 原題鏈結 ccf 201903 4訊息傳遞介面 思路 主要的思路是利用佇列來儲存每乙個程序的收發指令。一旦找到匹配的指令,則將這一對出佇列。直到某一次找不到匹配的指令了,退出迴圈。再判斷是不是所有的程序對應的收發指令佇列都為空。如果全部為空,則該程式不存在死鎖,否則程序存在死鎖。因為...

CCF 201903 4 試題名稱 訊息傳遞介面

參加了這場認證,及格分都沒拿到,最近準備二戰。當時感覺這道題寫得挺有把握的,結果只拿了60分,原因我就不說了,反正菜就對了。下面就來分享下做題思路 其實實現思路非常簡單,只是稍微有點繞。當你看測試樣例的時候,其實你腦袋裡就在模擬訊息傳遞的過程。其實這道題也就是模擬那個過程,沒有什麼獨特的演算法,最多...

CCF CSP題解 201903 4 訊息傳遞介面

求並行的各個程序,且程序內部順序執行的情況下,會不會出現 死鎖 首先用 n 將每個程序讀入。最後過不了居然是因為 str 開小了 悲喜交加。儲存在 中,並記錄每個程序的指令數 instnum 然後就是模擬。instcmp 記錄每個程序已完成的指令數,instblk 記錄每個程序是否阻塞,numcmp...