From eb9608f7297da6f9cc1e43dc2eefd43e317632fe Mon Sep 17 00:00:00 2001 From: Binoy Bhushan Barman Dipu <115131723+binoydipu@users.noreply.github.com> Date: Mon, 4 Nov 2024 00:39:27 +0600 Subject: [PATCH 1/3] Create 1039.md --- 1039.md | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 1039.md diff --git a/1039.md b/1039.md new file mode 100644 index 00000000..3228f03c --- /dev/null +++ b/1039.md @@ -0,0 +1,136 @@ +# LOJ 1039 - A Toy Company + +--- +Tags: Graph Theory, Breadth First Search/Depth First Search + +The problem statement has these key points: +1. A word can change in 6 possible ways +2. Some words are forbidden, so need to filter those while traversing +3. Each move costs 1, so bfs can be used to find the minimum path + +We need to reach the final word in minimum number of button presses. So first time we reach the final string. is our answer. + +## Solution (Key Points) + +1. We need three values to define a position, all possible 3 characters combination. +2. We need to check if starting word is forbidden or not before we run bfs. + +### Why we need to check starting word beforehand? + +Because if we push the node to queue than we will move to another word which might not be forbidden and get results. But if the starting word itself is forbidden than it is impossible to find an answer. We can also check this bofore running the while loop. Similarly, we need to check the final word, but it is taken care of inside the while loop. + +## Time Complexity + +Building Forbidden Words -> `O(26 * 26 * 26)` -> O($26 ^{3}$) + +Reading Array Values -> O(1) + +Array Memset -> O(3 * $26 ^{3}$) + +BFS traversal -> O($26 ^{3}$) + +Overall Complexity : O(T * 4 * $26 ^{3}$) + +## Solution in CPP + +```cpp +/** + * @author: Binoy Barman + * @created: 2024-11-03 22:31:02 +**/ + +#include +using namespace std; +#define nl '\n' +#define all(v) v.begin(), v.end() +#define Too_Many_Jobs int tts, tc = 1; cin >> tts; hell: while(tts--) +#define Dark_Lord_Binoy ios_base::sync_with_stdio(false); cin.tie(NULL); + +#ifdef LOCAL +#include "debug/whereisit.hpp" +#else +#define dbg(...) 42 +#endif +#define ll long long + +vector> moves = { + {1, 0, 0}, + {-1, 0, 0}, + {0, 1, 0}, + {0, -1, 0}, + {0, 0, 1}, + {0, 0, -1}, +}; +string st, ed; +array beg, endd; +bool fob[26][26][26], vis[26][26][26]; +int dis[26][26][26]; + +struct Bfs { + Bfs() { + memset(fob, 0, sizeof fob); // forbidden words + memset(vis, 0, sizeof vis); // visited words + memset(dis, 0, sizeof dis); // distance from starting word + } + bool bfs() { + vis[beg[0]][beg[1]][beg[2]] = true; + dis[beg[0]][beg[1]][beg[2]] = 0; + queue> q; + q.push(beg); + while(!q.empty()) { + array v = q.front(); + q.pop(); + if(v == endd) return true; + for(auto move : moves) { + array u = { + (v[0] + move[0] + 26) % 26, + (v[1] + move[1] + 26) % 26, + (v[2] + move[2] + 26) % 26 + }; + if(!vis[u[0]][u[1]][u[2]] && !fob[u[0]][u[1]][u[2]]) { + vis[u[0]][u[1]][u[2]] = true; + dis[u[0]][u[1]][u[2]] = 1 + dis[v[0]][v[1]][v[2]]; + q.push(u); + } + } + } + return false; + } +}; + +int32_t main() { +Dark_Lord_Binoy +#ifdef LOCAL + freopen("input.txt", "r", stdin); + freopen("output.txt", "w", stdout); +#endif + Too_Many_Jobs { + cin >> st >> ed; + beg = {st[0] - 'a', st[1] - 'a', st[2] - 'a'}; + endd = {ed[0] - 'a', ed[1] - 'a', ed[2] - 'a'}; + int n; + cin >> n; + Bfs g; + while(n--) { + string x, y, z; + cin >> x >> y >> z; + for(auto i : x) { + for(auto j : y) { + for(auto k : z) { + array cur = {i - 'a', j - 'a', k - 'a'}; + fob[cur[0]][cur[1]][cur[2]] = true; + } + } + } + } + cout << "Case " << tc++ << ": "; + if(fob[beg[0]][beg[1]][beg[2]]) { + cout << -1 << nl; + } else { + cout << (g.bfs() ? dis[endd[0]][endd[1]][endd[2]] : -1) << nl; + } + } + + return 0; +} +``` From 27d087ecdf856c07f8ad4394ff7cba3bb62b5f8e Mon Sep 17 00:00:00 2001 From: Binoy Bhushan Barman Dipu <115131723+binoydipu@users.noreply.github.com> Date: Mon, 4 Nov 2024 00:45:46 +0600 Subject: [PATCH 2/3] Delete 1039.md --- 1039.md | 136 -------------------------------------------------------- 1 file changed, 136 deletions(-) delete mode 100644 1039.md diff --git a/1039.md b/1039.md deleted file mode 100644 index 3228f03c..00000000 --- a/1039.md +++ /dev/null @@ -1,136 +0,0 @@ -# LOJ 1039 - A Toy Company - ---- -Tags: Graph Theory, Breadth First Search/Depth First Search - -The problem statement has these key points: -1. A word can change in 6 possible ways -2. Some words are forbidden, so need to filter those while traversing -3. Each move costs 1, so bfs can be used to find the minimum path - -We need to reach the final word in minimum number of button presses. So first time we reach the final string. is our answer. - -## Solution (Key Points) - -1. We need three values to define a position, all possible 3 characters combination. -2. We need to check if starting word is forbidden or not before we run bfs. - -### Why we need to check starting word beforehand? - -Because if we push the node to queue than we will move to another word which might not be forbidden and get results. But if the starting word itself is forbidden than it is impossible to find an answer. We can also check this bofore running the while loop. Similarly, we need to check the final word, but it is taken care of inside the while loop. - -## Time Complexity - -Building Forbidden Words -> `O(26 * 26 * 26)` -> O($26 ^{3}$) - -Reading Array Values -> O(1) - -Array Memset -> O(3 * $26 ^{3}$) - -BFS traversal -> O($26 ^{3}$) - -Overall Complexity : O(T * 4 * $26 ^{3}$) - -## Solution in CPP - -```cpp -/** - * @author: Binoy Barman - * @created: 2024-11-03 22:31:02 -**/ - -#include -using namespace std; -#define nl '\n' -#define all(v) v.begin(), v.end() -#define Too_Many_Jobs int tts, tc = 1; cin >> tts; hell: while(tts--) -#define Dark_Lord_Binoy ios_base::sync_with_stdio(false); cin.tie(NULL); - -#ifdef LOCAL -#include "debug/whereisit.hpp" -#else -#define dbg(...) 42 -#endif -#define ll long long - -vector> moves = { - {1, 0, 0}, - {-1, 0, 0}, - {0, 1, 0}, - {0, -1, 0}, - {0, 0, 1}, - {0, 0, -1}, -}; -string st, ed; -array beg, endd; -bool fob[26][26][26], vis[26][26][26]; -int dis[26][26][26]; - -struct Bfs { - Bfs() { - memset(fob, 0, sizeof fob); // forbidden words - memset(vis, 0, sizeof vis); // visited words - memset(dis, 0, sizeof dis); // distance from starting word - } - bool bfs() { - vis[beg[0]][beg[1]][beg[2]] = true; - dis[beg[0]][beg[1]][beg[2]] = 0; - queue> q; - q.push(beg); - while(!q.empty()) { - array v = q.front(); - q.pop(); - if(v == endd) return true; - for(auto move : moves) { - array u = { - (v[0] + move[0] + 26) % 26, - (v[1] + move[1] + 26) % 26, - (v[2] + move[2] + 26) % 26 - }; - if(!vis[u[0]][u[1]][u[2]] && !fob[u[0]][u[1]][u[2]]) { - vis[u[0]][u[1]][u[2]] = true; - dis[u[0]][u[1]][u[2]] = 1 + dis[v[0]][v[1]][v[2]]; - q.push(u); - } - } - } - return false; - } -}; - -int32_t main() { -Dark_Lord_Binoy -#ifdef LOCAL - freopen("input.txt", "r", stdin); - freopen("output.txt", "w", stdout); -#endif - Too_Many_Jobs { - cin >> st >> ed; - beg = {st[0] - 'a', st[1] - 'a', st[2] - 'a'}; - endd = {ed[0] - 'a', ed[1] - 'a', ed[2] - 'a'}; - int n; - cin >> n; - Bfs g; - while(n--) { - string x, y, z; - cin >> x >> y >> z; - for(auto i : x) { - for(auto j : y) { - for(auto k : z) { - array cur = {i - 'a', j - 'a', k - 'a'}; - fob[cur[0]][cur[1]][cur[2]] = true; - } - } - } - } - cout << "Case " << tc++ << ": "; - if(fob[beg[0]][beg[1]][beg[2]]) { - cout << -1 << nl; - } else { - cout << (g.bfs() ? dis[endd[0]][endd[1]][endd[2]] : -1) << nl; - } - } - - return 0; -} -``` From 18ccd8b6d4546858ca813cabfb120acbf8d684cc Mon Sep 17 00:00:00 2001 From: Binoy Bhushan Barman Dipu <115131723+binoydipu@users.noreply.github.com> Date: Mon, 4 Nov 2024 00:47:41 +0600 Subject: [PATCH 3/3] Added Tutorial of LightOJ 1039 - A Toy Company(en) --- 1039/en.md | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 1039/en.md diff --git a/1039/en.md b/1039/en.md new file mode 100644 index 00000000..6ee56b71 --- /dev/null +++ b/1039/en.md @@ -0,0 +1,136 @@ +# LOJ 1039 - A Toy Company + +--- +Tags: Graph Theory, Breadth First Search/Depth First Search + +The problem statement has these key points: +1. A word can change in 6 possible ways +2. Some words are forbidden, so need to filter those while traversing +3. Each move costs 1, so bfs can be used to find the minimum path + +We need to reach the final word in minimum number of button presses. So first time we reach the final string. is our answer. + +## Solution (Key Points) + +1. We need three values to define a position, all possible 3 characters combination. +2. We need to check if starting word is forbidden or not before we run bfs. + +### Why we need to check starting word beforehand? + +Because if we push the node to queue than we will move to another word which might not be forbidden and get results. But if the starting word itself is forbidden than it is impossible to find an answer. We can also check this bofore running the while loop. Similarly, we need to check the final word, but it is taken care of inside the while loop. + +## Time Complexity + +Building Forbidden Words -> `O(26 * 26 * 26)` -> O($26 ^{3}$) + +Reading Array Values -> O(1) + +Array Memset -> O(3 * $26 ^{3}$) + +BFS traversal -> O($26 ^{3}$) + +Overall Complexity : O(T * 4 * $26 ^{3}$) + +## Solution in CPP + +```cpp +/** + * @author: Binoy Barman + * @created: 2024-11-03 22:31:02 +**/ + +#include +using namespace std; +#define nl '\n' +#define all(v) v.begin(), v.end() +#define Too_Many_Jobs int tts, tc = 1; cin >> tts; hell: while(tts--) +#define Dark_Lord_Binoy ios_base::sync_with_stdio(false); cin.tie(NULL); + +#ifdef LOCAL +#include "debug/whereisit.hpp" +#else +#define dbg(...) 42 +#endif +#define ll long long + +vector> moves = { + {1, 0, 0}, + {-1, 0, 0}, + {0, 1, 0}, + {0, -1, 0}, + {0, 0, 1}, + {0, 0, -1}, +}; +string st, ed; +array beg, endd; +bool fob[26][26][26], vis[26][26][26]; +int dis[26][26][26]; + +struct Bfs { + Bfs() { + memset(fob, 0, sizeof fob); // forbidden words + memset(vis, 0, sizeof vis); // visited words + memset(dis, 0, sizeof dis); // distance from starting word + } + bool bfs() { + vis[beg[0]][beg[1]][beg[2]] = true; + dis[beg[0]][beg[1]][beg[2]] = 0; + queue> q; + q.push(beg); + while(!q.empty()) { + array v = q.front(); + q.pop(); + if(v == endd) return true; + for(auto move : moves) { + array u = { + (v[0] + move[0] + 26) % 26, + (v[1] + move[1] + 26) % 26, + (v[2] + move[2] + 26) % 26 + }; + if(!vis[u[0]][u[1]][u[2]] && !fob[u[0]][u[1]][u[2]]) { + vis[u[0]][u[1]][u[2]] = true; + dis[u[0]][u[1]][u[2]] = 1 + dis[v[0]][v[1]][v[2]]; + q.push(u); + } + } + } + return false; + } +}; + +int32_t main() { +Dark_Lord_Binoy +#ifdef LOCAL + freopen("input.txt", "r", stdin); + freopen("output.txt", "w", stdout); +#endif + Too_Many_Jobs { + cin >> st >> ed; + beg = {st[0] - 'a', st[1] - 'a', st[2] - 'a'}; + endd = {ed[0] - 'a', ed[1] - 'a', ed[2] - 'a'}; + int n; + cin >> n; + Bfs g; + while(n--) { + string x, y, z; + cin >> x >> y >> z; + for(auto i : x) { + for(auto j : y) { + for(auto k : z) { + array cur = {i - 'a', j - 'a', k - 'a'}; + fob[cur[0]][cur[1]][cur[2]] = true; + } + } + } + } + cout << "Case " << tc++ << ": "; + if(fob[beg[0]][beg[1]][beg[2]]) { + cout << -1 << nl; + } else { + cout << (g.bfs() ? dis[endd[0]][endd[1]][endd[2]] : -1) << nl; + } + } + + return 0; +} +``` \ No newline at end of file