目前我正试图解决https://open.kattis.com/problems/animal。我的代码可以在这里找到:http://pastebin.com/xgXiDj91。我是竞争性编程和C ++的新手。话虽如此,我的方法是解析输入字符串[例如(1,(2,(3,(4,(5,(6,(7,(8,(9,10)))))))))]列表[((3(1(52) ))4)]。之后我会记下所有元素,将它分成两个子树,然后将它们重新添加到队列中,重新开始,直到没有任何东西可以分割为止。然后我比较我用这种方式获得的两组。如果我没有弄错,这应该导致O(Nlog(N))的复杂性,因为对于每个子树,我需要收集属于它的所有元素,这相当于完整二叉树中的Nlog(N)。这适用于提供的测试集,但超出了提交的时间限制。
你能帮我弄清楚我可以在哪些方面改进我的代码以及我做得不好吗?
亲爱的问候, 米莎。
PS:这是我的代码:
#include <iostream>
#include <list>
#include <algorithm>
#include <string>
#include <unordered_set>
#include <deque>
using namespace std;
struct hash_X{
size_t operator()(const unordered_set<int> &x) const{
int sum = 0;
for(int i: x){sum = sum+i;}
return sum;
}
};
unordered_set<unordered_set<int>, hash_X> mt(list<string> L){
unordered_set<unordered_set<int>, hash_X> S;
list<string> K;
deque<list<string>> Q;
Q.push_back(L);
while(not Q.empty()){
K = Q.back();
unordered_set<int> tmp;
for(string s: K){if( s!="(" and s!=")" ){int i = stoi(s); tmp.insert(i);}}
S.insert(tmp);
//K is of the form for example (x(yz)), so first we unwrap ~ x(yz) and split into the two subtrees x and (yz)
//and add both to the queue. If only one node is left ( x ) we dont add it back to the queue
if(K.size() >= 2){
K.pop_front();
K.pop_back();
list<string>::iterator it = K.begin();
if(*it == "("){
int i = 1;
while(i != 0){
it++;
if(*it == ")"){i = i-1;}
else if(*it == "("){i=i+1;}
}
}
it++;
list<string> B;
list<string>::iterator itB = B.begin();
B.splice(itB, K, it, K.end());
Q.push_front(K);
Q.push_front(B);
}
Q.pop_back();
}
return S;
}
int main(){
int n;
string x, y;
char c;
list<string> A, B;
cin >> n;
cin.ignore();
cin >> x;
cin >> y;
// parse "((3,(1,(5,2))),4)" into ((3(1(52)))4)
for(int i = 0; i < x.size(); i++){
string c = "";
c += x[i];
if( c == "(" or c == ")" ){A.push_back(c);}
if( isdigit(x[i]) ){
string tmp = "";
while( isdigit(x[i]) ){
tmp += x[i];
i++;
}
i--;
A.push_back(tmp);
}
}
for(int i = 0; i <= y.size(); i++){
string c = "";
c += y[i];
if( c == "(" or c == ")" ){B.push_back(c);}
if( isdigit(y[i]) ){
string tmp = "";
while( isdigit(y[i]) ){
tmp += y[i];
i++;
}
i--;
B.push_back(tmp);
}
}
// make the trees
unordered_set<unordered_set<int>, hash_X> t1 = mt(A);
unordered_set<unordered_set<int>, hash_X> t2 = mt(B);
unordered_set<unordered_set<int>, hash_X> i(t1.begin(), t1.end());
int res = count_if(t2.begin(), t2.end(), [&](unordered_set<int> k) {return i.find(k) != i.end();});
cout << res;
}