邏輯思路:
1、如果甲要取勝,那麼對甲來說,面對的字串,劃掉1個字元,必然勝利。
2、如果劃掉乙個字元,甲不能確定取勝,那麼甲有n種劃法,假設現在甲面對的字串長度為n。比如:abcab,那麼甲有5種劃法,分別是劃掉第乙個,第二個.......字元。如果甲想取勝,那麼,至少有一種劃法,劃掉乙個字元後,交給乙,乙必然失敗才行。
3、對於甲劃掉的字元,交給乙,對乙來說,面對和甲相同的判斷,及需要判斷1,2步驟。
由上面分析,可以看出,乙個簡單的遞迴就可以解決了。下面開寫。
首先寫第乙個函式:
判斷字串,劃掉某乙個字元,是不是必然勝利
private bool wincheck(string word)
else
else}}
if (count >= 2)
else
else
else
else}}
}return flag;
}這個函式邏輯很簡單,就是迴圈以下這個字串,看看劃掉某乙個字串是不是形成乙個單調遞增的序列。
第一步的判斷函式寫好了。
第二步,由於甲和乙的判斷邏輯一樣,所以**可以整合,引數就是word,表示需要判斷的字串,who表示是誰對當前字串進行判斷。
這個判斷的邏輯就是:
1、判斷當前字串是否能夠必勝。
2、不能夠,則遍歷所有可能字串長度n種可能,只要有一種可能,保證自己必勝,那麼就劃掉這個字元。
private int checkall(string word, int who)
else}}
return result;
}ok,到此,所有邏輯完成,看看**,真的還是比較簡潔的。
提交,執行,結果是出來了,不過時間是超過3s了。
看來還需要再優化。
問題來了,優化**呢?將遞迴呼叫轉換成迭代,但是分析了下,次數並不會減少啊。
看來此路不通啊。
wincheck函式只迴圈了一次,看看,問題不在這裡。
問題出在遞迴呼叫上,浪費了大量時間。
再分析遞迴呼叫的邏輯,當乙個人劃掉乙個字元後,交給另乙個人去判斷,會不會出現很多次,即之前這個字串已經判斷過,並確定了一定是某人勝利?簡單分析後,發現出現頻率很高,意味著做了很多重複無用功,因此,用乙個變數來儲存。
我們就選用private dictionarydic;來儲存,字串,int表示誰勝利,這裡還有乙個簡單的判斷,即甲和乙不可能遇到一模一樣的字串(為什麼?交給大家想想)
改造下checkall函式:
private int checkall(string word, int who)
}else
else
}if (result == who)}}
return result;
}現在再執行,輸入15位的隨機字串,呵呵,都是0.01秒左右,蠻好,完成。
物件導向的理解,答案整理
說道物件導向,首先想到的就是物件導向的三大特徵 封裝 繼承 多型 我們想簡單說一下這三個的含義 1.封裝 這是物件導向最核心的特徵。每個物件包含所能操作的所有資訊,通過例項化類來生成物件。封裝就像建房子,類就是房子,屬性是門窗,欄位是房子裡的東西,方法是人的行為。屬性對字段有保護作用,防止欄位被隨意...
牛客題霸 樹的直徑 C 題解 答案
牛客題霸 樹的直徑 c 題解 答案 給定一棵樹,求出這棵樹的直徑,即兩個節點距離的最大值。不知道大家聽沒聽過乙個結論 樹的直徑可以通過兩邊dfs找到 步驟 1.從任意一點進行dfs,然後找到乙個最長路徑,記錄最遠點u 2.然後從u再進行dfs,找最長路徑,記錄一點v。u,v 就是樹的直徑 證明 我們...
牛客題霸 樹的直徑 C 題解 答案
牛客題霸 樹的直徑 c 題解 答案 給定一棵樹,求出這棵樹的直徑,即兩個節點距離的最大值。不知道大家聽沒聽過乙個結論 樹的直徑可以通過兩邊dfs找到 步驟 1.從任意一點進行dfs,然後找到乙個最長路徑,記錄最遠點u 2.然後從u再進行dfs,找最長路徑,記錄一點v。u,v 就是樹的直徑 證明 我們...