I tried solving the following problem by following the suggested approach to solving the problem in the problem tutorial. However, the online judge still says my solution exceeds the time limit. Is there a way to optimize the program to perform faster?
The Problem:
You are given \$n\$ strings \$s_1, s_2, \dots, s_n\$ of length at most 8.
For each string \$s_i\$, determine if there exist two strings \$s_j\$ and \$s_k\$ such that \$s_i = s_j + s_k\$. That is, \$s_i\$ is the concatenation of \$s_j\$ and \$s_k\$. Note that \$j\$ can be equal to \$k\$.
Recall that the concatenation of strings \$s\$ and \$t\$ is \$s + t = s_1 s_2 \dots s_p t_1 t_2 \dots p_q\$, where \$p\$ and \$q\$ are the lengths of strings \$s\$ and \$t\$ respectively. For example, concatenation of "code" and "forces" is "codeforces".
Input
The first line contains a single integer \$t\$ (\$1 \leq t \leq 10^4\$) — the number of test cases.
The first line of each test case contains a single integer \$n\$ (\$1 \leq n \leq 10^5\$) — the number of strings.
Then \$n\$ lines follow, the \$i\$-th of which contains non-empty string \$s_i\$ of length at most 8, consisting of lowercase English letters. Among the given \$n\$ strings, there may be duplicates.
The sum of \$n\$ over all test cases doesn't exceed \$10^5\$.
Output
For each test case, output a binary string of length \$n\$. The \$i\$-th bit should be 1 if there exist two strings \$s_j\$ and \$s_k\$ where \$s_i = s_j + s_k\$, and 0 otherwise. Note that \$j\$ can be equal to \$k\$.
Example
Input:
3 5 abab ab abc abacb c 3 x xx xxx 8 codeforc es codes cod forc forces e code
Output:
10100 011 10100101
The Problem Tutorial (Hint):
Use some data structure that allows you to answer queries of the form: "does the string \$t\$ appear in the array \$s_1, \dots, s_n\$?" For example, in C++ you can use a
map<string, bool>
, while in Python you can use a dictionary.Afterwards, for each string \$s\$, brute force all strings \$x\$ and \$y\$ such that \$s=x+y\$. There are at most 7 such strings, because \$s\$ has length at most 8. Then check if both \$x\$ and \$y\$ appear in the array using your data structure.
The time complexity is \$O(ℓ n \log n)\$ per test case, where \$ℓ\$ is the maximum length of an input string.
My Solution
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
int tests;
cin >> tests;
for (int i = 0; i < tests; i++) { //one loop per each test case
int NumOfStrings;
cin >> NumOfStrings;
unordered_map<string, bool> phrases;
string words[100000];
for (int j = 0; j < NumOfStrings; j++) { // adds all input strings for each test case into words and phrases
string temp;
cin >> temp;
phrases.insert({ temp, false });
words[j] = temp;
}
for (int k = 0; k < NumOfStrings; k++) { // loop for each string in the test case
int len = words[k].length(); // len is length of current word
for (int o = 0; o < len; o++) { // loops through current word
string partition1 = "";
string partition2 = "";
for (int m = 0; m <= o; m++) {
partition1 += words[k][m];
}
for (int n = o+1; n < len; n++) {
partition2 += words[k][n];
}
if (phrases.find(partition1) != phrases.end() && phrases.find(partition2) != phrases.end()) { //if both substrings exist in the map, then value for word is 1.
phrases[words[k]] = true;
}
}
}
for (int j = 0; j < NumOfStrings; j++) {
int value = 0;
if (phrases[words[j]] == true) value = 1;
cout << value;
}
cout << endl;
}
return 0;
}