1. 程式人生 > 其它 >10.14 模擬考試

10.14 模擬考試

沒有摘要的摘要

10.14 模擬考試 題解報告

目錄

水題模擬賽

T2 的資料真的...

顯然沒有什麼需要整理的


考試過程

讀完題發現好像不是特別難的亞子...

然後 T1

寫 寫完過不了樣例 然後就調 寫過了樣例之後寫暴力 然後寫對拍

然後就拍 然後就掛了 然後再調 再拍 再掛...

然後一個小時就沒了

理了一下思路 重構程式碼 然後把對拍掛上 開 T2

想法比較暴力 直接把所有串丟到 Trie 樹裡面 然後 dfs 大力迭代

半個小時過樣例直接跑路

T3 的部分分可以直接暴力 dp

dp 陣列是一個 01 的形式 然後嘗試構造矩陣 發現確實可以

然後就大力線段樹維護矩陣乘

碼 調 寫了個對拍拍上

又回頭自己卡了一下 T2 差不多就三個小時多了

雖然最後 T2 還是沒過

T2 最後一個點被構造的資料卡掉了 當時看到這資料的時候蠻驚訝的

大概是這麼個情況

看到後面那個 0 KB 大概就知道事情不大對...

讀入大概是這樣的

然後就被那一個 b 卡沒了 dfs 迭代的時候接近跑滿...

後來又試了一下 好像把那個 b 刪了也跑不過去 但那就是資料的問題了

再然後就是這組輸入是沒有輸出的... 所以如果在 dfs 的時候卡一下時也能過


得分情況

100 + 90 + 100 = 290

差了億點點...


題解

鍾神的題當然沒有題解


T1 加加減減

手玩一下資料的話 大概可以發現如果將陣列從小到大的話 存在一個分界線 左邊全是加 右邊全是減 當然這個分界線有可能在兩端

全加和全減沒什麼區別 答案都是原陣列最大減最小

再列舉分界線的位置 看一下兩邊是否分別成為最大值或最小值 更新答案即可


程式碼


T2 英文分詞

_ 的字典序是比字母小的 所以能插的儘量插

把所以串丟到 Trie 裡面 然後通過 dfs 進行匹配 貪心的匹配即可

然後這個方法會被最後一個構造的資料卡掉...

卡掉的原因是因為超時 而最後一個點的資料又沒有輸出

這就啟示了對演算法的優化:

直接面向資料進行卡時 TLE 之前退出這個點就可以過啦 反正這個點也沒有輸出(霧

其實個人感覺這樣做是沒什麼問題的

因為原題中有這樣的一句話

匹配的程式碼是這樣的

void dfs(int x) {
	if(x == m + 1)
	{
		if(!top) return ;
		int l = 0;
		for(int i = 1; i < top; ++i)
		{
			for(int j = l + 1; j <= st[i]; ++j)
				putchar(s[j]);
			putchar('_'); l = st[i];
		}
		for(int j = l + 1; j <= st[top]; ++j) putchar(s[j]); pn;
		return ;
	}
	for(int p = 0, i = x; ; ++i)
	{
		int k = s[i] - 96;
		if(!t[p][k]) return ;
		p = t[p][k];
		if(ed[p])
		{
			st[++top] = i;
			dfs(i + 1);
			--top;
		}
	}
}

貪心的匹配 匹配成功之後標記這個位置 繼續匹配下一個位置

卡掉的原因從上面那組資料中也能看出來 幾乎每個字元都可以進行匹配 迭代次數太多

複雜度差不多能到 \(O(2^{|T|})\) 這裡的 \(T\) 是文字串

那為什麼直接卡時不輸出呢 因為這個資料如果有輸出的話 僅輸出就會超時 可行的情況實在太多了

所以能夠正常輸出的量級卡不掉這個迭代 能卡掉的就沒有輸出了

當然不排除有這裡沒想到的資料 但是就算有的話應該也比較難構造


程式碼


T3 內需消費

首先有一個比較顯然的 \(dp\)

\(f_{i, 0/1}\) 表示到 \(i\) 位置 手中是否有物品的最大價值

轉移考慮買入或賣出

\[f_{i, 0} = \max(f_{i - 1, 0}, f_{i - 1, 1} + a_i)\\ f_{i, 1} = \max(f_{i - 1, 0} - a_i, f_{i - 1, 1}) \]

暴力的話直接每次詢問 \(dp\) 一遍 \(l \leq r\) 的時候從左向右進行 \(dp\) 否則從右向左進行 \(dp\)

然後這個是需要帶修的 考慮能不能通過矩陣乘法進行轉移 矩陣也不難構造

定義矩陣運算子 \(\oplus\) :

\[C_{i, j} = \min_{k = 1}^n\left(A_{i, k} + B_{k, j}\right) \]

有:

\[\begin{vmatrix} f_{i - 1, 0} & f_{i - 1, 1}\end{vmatrix} \oplus \begin{vmatrix} 0 & -a_i\\a_i & 0 \end{vmatrix} = \begin{vmatrix} f_{i, 0} & f_{i, 1} \end{vmatrix} \]

直接上線段樹 維護廣義矩陣乘

修改就是單點修改 查詢就是區間求和

正反各維護一遍即可


程式碼