鑑於是上學期的陳題,沒什麼過多可以說的,具體內容請查詢「角谷猜想」。
此外,原本想考察乙個叫「阿克曼函式」的遞迴函式,但是由於該函式在時間與數值上的增長率都十分迅猛,因此沒有設題,有興趣練習一下的同學可以自行查閱並練習一下。
//by trashlhc
#includeusing namespace std;
int cube(int n)
int main()
return 0;
}
//by wjfwzzc
//non-recursive version
#include#include#include#includeusing namespace std;
stack> s;
int main()
int num=0;
for(; isdigit(str[i]); ++i)
num=num*10+str[i]-'0';
if(num==0)
++num;
if(str[i]=='(')
while(num--)
ans+=str[i];
}while(!s.empty())
cout<
其實對一些同學用string類自帶的庫過了這道題表示不明覺厲= =
後來查了一下,c++中的string::find()函式似乎是最樸素的bf演算法加上了隨機化演算法的……所以其平均時間複雜度會比o(m*n)稍稍少那麼一些。並且在小資料上kmp的優勢體現不出來,而這道題的資料又很大程度上是隨機生成的……
嘛,不過還是提供kmp的演算法,畢竟是乙個十分重要的東西。而且從兩種方法的ac耗時上可以看出,kmp還是很有優勢的。
不多說,進入解題分析。
這道題中的萬用字元是乙個神奇的東西,它能匹配任意數量的一段連續字元(就算數目為0也是可以的,很多同學都跪在了這個上面)由於這一附加萬用字元,導致的結果就是要麼我們對kmp演算法進行大改,要麼就要對模式串進行一定處理。大改kmp當年某渣在上機的時候因為技術太弱沒能寫出來(這一年也沒能寫出來……),於是在這裡提供修改模式串的版本。
大致的思路就是以萬用字元為分隔符,將整個模式串分成不同小段的子串。每乙個子串與待匹配串進行一次kmp,得到每一段在文中的位置。如果匹配上了的話,所有匹配的位置將會是乙個公升序的序列,反之一旦這個位置序列的任意位置出現非公升序的情況,則模式串與待匹配串不匹配。
這裡有同學要問了,那如果某乙個子串在帶匹配串中出現了多次呢?由於演算法是從左到右掃瞄待匹配串的,因此只需要匹配第乙個位置就可以了。這個具體的證明大家可以試著推一推,在這裡不再贅述。
//by trashlhc
//專門重寫了乙份kmp,表示某渣當年上資料結構的時候kmp寫得實在是太不優雅了……
#include#include#include#include#define maxsize 9998
#define maxl 100
#define maxn 101
using namespace std;
void getnextval(char t,int nextval)
//稍稍改寫了一點的kmp,由於基於萬用字元對模式串進行了分解,因此這裡每一段進行匹配時,其起始匹配位置不一定為0,而是startpos。
int placeres[maxn]; //placeres用於儲存每一模式子串對應的匹配位置。
char s[maxsize],t[maxsize],splitres[maxn][maxl];
//s為模式串,t為待匹配串,splitres用於儲存s串分解後的模式子串組
void init()
//init函式用於初始化所有的字串,及placeres陣列。
void reshape()box;
typedef struct
qutype;
void print(qutype qu,int front,int number)
while(k!=0);
k=0;
while(k>length>>width)
if(map[i][j]=='z')//獲取重點位置
} printf("where?!\n");//終點不存在或無法到達終點
}}
首先……那個神馬神馬數是個神馬東西?
嘛,暫且不管那個,先看看遞迴模式:
假設現在排隊的人有x個拿著五西斯,y個人拿著十西斯
我們可以很輕易地知道兩個結論:
① 若x② 若y=0,那麼thor一定可以找開錢,而且由於題目描述,這樣只會有一種排隊方式。
除了上面兩種情況外,最普通的情況——x>y的情況下,現在隊中有x+y個人,對於第x+y個人,有兩種可能:他拿著十西斯,他拿著五西斯。
假設這x+y個人有f(x,y)中排隊方式,於是又有了兩個結論:
① 若第x+y個人拿著五西斯,那麼在這種情況下他前面x+y-1個人中有x-1個人拿著五西斯,y個人拿著十西斯,於是這種情況下排隊方式有f(x-1,y)種。
② 若第x+y個人拿著十西斯,那麼在這種情況下他前面x+y-1個人中有x個人拿著五西斯,y-1個人拿著十西斯,於是這種情況下排隊方式有f(x,y-1)種。
於是遞迴式得到:
str+=str; //string類過載了加法運算子
}cout
using namespace std;
typedef char elemtype;
typedef struct
sqstring;
void strassign(sqstring &s,char cstr)
void insstr(sqstring &s1,int i,sqstring s2)
if(manipulate=="del")
if(manipulate=="copy")
insstr(str,str.length,str);
}dispstr(str);
}本題再一次證明了學習英語的重要性= =
a line containing a period follows the lasttest case.
上面這句話的意思是輸入資料以包含點號的一行結束。
某渣的思路是不斷地從頭開始擷取不同長度的子串,看這個串是否可以通過自我重複得到完整的字串。由於長度是從小到大,從1到字串長度的一半依次選擇,因此第一次出現滿足條件的字串必然長度最短,其重複次數也必然是最多的。
但是——
正解非以上,在字串長度較大的時候上述演算法會跪掉= =
那麼正解究竟是什麼呢?
參考標準**解決好了~
//by trashlhc
//folk version
#include#include#includeusing namespace std;
int main()
}
//official version
#include #include #include using namespace std;
const intn=1000010;
int len,nextt[n];
char str[n];
int get_next()
{ nextt[0]=0;
for(int i=1;i
第三次資料結構上機
實驗題目 編寫乙個程式exp3 6.cpp,求解皇后問題 在n n的方格棋盤上,放置n個皇后,要求每個皇后不同行 不同列 不同左右對角線。要求 1 皇后的個數n由使用者輸入,其值不能超過20,輸出所有的解。2 採用類似於棧求解迷宮問題的方法。實驗步驟 包括基本設計思路 演算法設計 函式相關說明 輸入...
C 第三次上機
題目一 假設有乙個字串strfilename d c 程式設計 實驗3 myfile.txt 使用字串方法,取出路徑中的檔名 myfile.txt 要求至少想出三種方法實現 1 using system using system.collections.generic using system.li...
PTA第三次上機
include include include using namespace std class polygon int perimeter 計算多邊形邊長 void display 輸出多邊形邊數和周長 int reachsidelen int polygon perimeter return ...