HDU 1671 (字典樹 || string + vector)
阿新 • • 發佈:2018-12-22
目錄
題意:
T個案例,每一個案例給一個n,代表有n個號碼,接著輸入n個號碼。
如果其中有一個號碼是另一個號碼的字首則輸出NO,否則輸出YES。
思路:
1.字典樹
第一反應是字典樹、字首樹嘛……但是之前覺得就很難,不敢寫,然後今天鼓起勇氣研究了一下字典樹,事實上也沒那麼難,重點在於對末尾的判斷,一個是對當前串的判斷,另一個是樹裡的串,所以其實字串的末尾很重要,這邊還是作死用的string,現在想來可能char陣列的'/0'判斷起來還會清晰很多。如果是要統計一個字元出現的次數只要把tail的型別改成int感覺應該也不會很難,但我的話應該會首選map,啊……統計字首的數量也可以用字典樹這麼搞,一會看看有沒有題目。
還有一個問題是記憶體回收的問題,因為這個問題mle了好幾次,也是作死要用new去開空間的關係,如果直接用陣列開好變數空間那麼空間就可以重複使用,也不用去new記憶體了,然後就是遞歸回收的時候要注意。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <map> #include <vector> #include <set> #include <queue> using namespace std; int flag; struct node { bool tail; node* next[10]; void init() { tail = false; for (int i = 0; i < 10; i++) next[i] = NULL; } }; node *newnode() { node *nnode = new node; nnode->init(); return nnode; } void insert(node *root,string s) { int len = s.length(); for (int i = 0; i < len; i++) { int id = s[i] - '0'; if (root->next[id] == NULL) { root->next[id] = newnode(); } else if (root->next[id] != NULL && i == len - 1)//&& 前的可以省略 原因是if語句中的內容與其相反 這裡也要判斷是因為當一個字串的最後一個字元也在樹中存在時,即該字串全部在樹中存在。 { flag = 0; return; } root = root->next[id]; if (root->tail == true)//即有一個字串到這裡是末尾了 那麼之前那個字串就是本字串的字首。 { flag = 0; return; } } root->tail = true; } void del(node *p) { if (p == NULL)return; for (int i = 0; i < 10; i++) { if (p->next[i]) del(p->next[i]); } delete p; } int main() { //ios::sync_with_stdio(false); //cin.tie(0); int T; cin >> T; while (T--) { int n; cin >> n; string s; flag = 1; node* root=newnode(); for (int i = 0; i < n; i++) { cin >> s; if (flag) { insert(root, s); } } if (flag) cout << "YES" << endl; else cout << "NO" << endl; del(root); } system("pause"); return 0; }
2.string+vector
當時也是討論區看到的。
vector沒有find可是string有鴨……(其實我也是剛知道= =||| )值的一提的是find函式返回的是找到的位置,如果找不到會返回一個相當於-1的值。
但是……但是……如果兩重迴圈去挨個找當前號碼是不是其他號碼的字首,會超時,很遺憾我再次嘗試這個題目的時候還是會遇到這樣的錯誤,我只能佩服第一個想出這個方法(sort + v[i].find(v[i-1]))的大佬,我覺得這需要對字典序很敏感才能想到。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <map> #include <vector> #include <set> #include <queue> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while (T--) { int n; cin >> n; string s; vector<string>v; for (int i = 0; i < n; i++) { cin >> s; v.push_back(s); } sort(v.begin(), v.end()); int flag = 1; for (int i = 0; i < v.size() && flag; i++) { if (v[i].find(v[i - 1]) != -1) { flag = 0; } } //for (int i = 0; i < v.size() && flag; i++)//TLE = =||| //{ // for (int j = 0; j < v.size() && flag; j++) // { // if (i == j)continue; // if (v[j].find(v[i])!=-1) // { // flag = 0; // } // } //} if (flag) cout << "YES" << endl; else cout << "NO" << endl; } system("pause"); return 0; }