https://vjudge.net/problem/UVA-10391
给一堆单词,其中有些单词可以由其他两个单词(可以相同)复合得到,输出符合这个性质的所有单词。\(n\le 120000\)
把所有单词存进set,然后枚举两个单词,加起来在set里面查找。时间复杂度\(O(n^2)\) \(\mathbb{TLE}\)
放弃了:(
反过来把一个单词拆成两个单词。可以用string的 c_str() 或 data() 函数,得到只读的C风格字符串,时间复杂度\(O(n\log n)\)
c++11以前c_str()返回的指针是以‘\0‘结尾的,而data()并不要求这一点。
https://en.cppreference.com/w/cpp/string/basic_string/c_str
https://en.cppreference.com/w/cpp/string/basic_string/data
所以还是用c_str()吧……
AC代码
#include <bits/stdc++.h>
#define REP(i,x,y) for(register int i=x; i<(y); i++)
#define REPE(i,x,y) for(register int i=x; i<=(y); i++)
#ifdef LOCAL
#define DBG(x,...) printf(x, ##__VA_ARGS__)
#else
#define DBG(x,...) (void)(0)
#endif
using namespace std;
set<string> st;
set<string> ans;
int main()
{
char s[1007];
while(~scanf("%s", s)) st.insert(s);
for(set<string>::iterator it=st.begin(); it!=st.end(); it++) {
string now = *it;
char sa[1007], sb[1007];
strcpy(sa,now.c_str());
strcpy(sb,now.c_str());
for(int i=now.size()-1; i>0; i--) {
sa[i]=0;
if(st.count(sa) && st.count(&sb[i])) {
ans.insert(now);
}
}
}
for(set<string>::iterator it=ans.begin(); it!=ans.end(); it++) {
cout << *it << endl;
}
return 0;
}
其实还可以加个字符串数组,减小常数……
原文:https://www.cnblogs.com/sahdsg/p/10367285.html