|
| 1 | +# [Fox and Names](https://codeforces.com/contest/510/problem/C) |
| 2 | + |
| 3 | +<div class="problem-statement"> <div class="header"> <div class="title">C. Fox And Names</div> <div class="time-limit"> <div class="property-title">time limit per test</div>2 seconds</div> <div class="memory-limit"> <div class="property-title">memory limit per test</div>256 megabytes</div> <div class="input-file"> <div class="property-title">input</div>standard input</div> <div class="output-file"> <div class="property-title">output</div>standard output</div></div> <div> <p>Fox Ciel is going to publish a paper on FOCS (Foxes Operated Computer Systems, pronounce: "Fox"). She heard a rumor: the authors list on the paper is always sorted in the <span class="tex-font-style-underline">lexicographical</span> order. </p> <p>After checking some examples, she found out that sometimes it wasn't true. On some papers authors' names weren't sorted in <span class="tex-font-style-underline">lexicographical</span> order in normal sense. But it was always true that after some modification of the order of letters in alphabet, the order of authors becomes <span class="tex-font-style-underline">lexicographical</span>!</p> <p>She wants to know, if there exists an order of letters in Latin alphabet such that the names on the paper she is submitting are following in the <span class="tex-font-style-underline">lexicographical</span> order. If so, you should find out any such order.</p> <p> <span class="tex-font-style-underline">Lexicographical</span> order is defined in following way. When we compare <span class="tex-span"> <i>s</i></span> and <span class="tex-span"> <i>t</i></span>, first we find the leftmost position with differing characters: <span class="tex-span"> <i>s</i> <sub class="lower-index"> <i>i</i></sub> ≠ <i>t</i> <sub class="lower-index"> <i>i</i></sub></span>. If there is no such position (i. e. <span class="tex-span"> <i>s</i></span> is a prefix of <span class="tex-span"> <i>t</i></span> or vice versa) the shortest string is less. Otherwise, we compare characters <span class="tex-span"> <i>s</i> <sub class="lower-index"> <i>i</i></sub></span> and <span class="tex-span"> <i>t</i> <sub class="lower-index"> <i>i</i></sub></span> according to their order in alphabet.</p></div> <div class="input-specification"> <div class="section-title">Input</div> <p>The first line contains an integer <span class="tex-span"> <i>n</i></span> (<span class="tex-span">1 ≤ <i>n</i> ≤ 100</span>): number of names.</p> <p>Each of the following <span class="tex-span"> <i>n</i></span> lines contain one string <span class="tex-span"> <i>name</i> <sub class="lower-index"> <i>i</i></sub></span> (<span class="tex-span">1 ≤ |<i>name</i> <sub class="lower-index"> <i>i</i></sub>| ≤ 100</span>), the <span class="tex-span"> <i>i</i></span>-th name. Each name contains only lowercase Latin letters. All names are different.</p></div> <div class="output-specification"> <div class="section-title">Output</div> <p>If there exists such order of letters that the given names are sorted lexicographically, output any such order as a permutation of characters 'a'–'z' (i. e. first output the first letter of the modified alphabet, then the second, and so on).</p> <p>Otherwise output a single word "Impossible" (without quotes).</p></div> <div class="sample-tests"> <div class="section-title">Examples</div> <div class="sample-test"> <div class="input"> <div class="title">Input<div title="Copy" data-clipboard-target="#id0047712434416716754" id="id005306748541724176" class="input-output-copier">Copy</div></div> <pre id="id0047712434416716754">3<br>rivest<br>shamir<br>adleman<br></pre></div> <div class="output"> <div class="title">Output<div title="Copy" data-clipboard-target="#id00910818824933006" id="id009543982272196343" class="input-output-copier">Copy</div></div> <pre id="id00910818824933006">bcdefghijklmnopqrsatuvwxyz<br></pre></div> <div class="input"> <div class="title">Input<div title="Copy" data-clipboard-target="#id002388487012888436" id="id005430558037252329" class="input-output-copier">Copy</div></div> <pre id="id002388487012888436">10<br>tourist<br>petr<br>wjmzbmr<br>yeputons<br>vepifanov<br>scottwu<br>oooooooooooooooo<br>subscriber<br>rowdark<br>tankengineer<br></pre></div> <div class="output"> <div class="title">Output<div title="Copy" data-clipboard-target="#id005914977943989022" id="id00508145167718012" class="input-output-copier">Copy</div></div> <pre id="id005914977943989022">Impossible<br></pre></div> <div class="input"> <div class="title">Input<div title="Copy" data-clipboard-target="#id003705258721664211" id="id005026967956215982" class="input-output-copier">Copy</div></div> <pre id="id003705258721664211">10<br>petr<br>egor<br>endagorion<br>feferivan<br>ilovetanyaromanova<br>kostka<br>dmitriyh<br>maratsnowbear<br>bredorjaguarturnik<br>cgyforever<br></pre></div> <div class="output"> <div class="title">Output<div title="Copy" data-clipboard-target="#id008150708744113269" id="id003510007903748298" class="input-output-copier">Copy</div></div> <pre id="id008150708744113269">aghjlnopefikdmbcqrstuvwxyz<br></pre></div> <div class="input"> <div class="title">Input<div title="Copy" data-clipboard-target="#id0019654425752322746" id="id005916429744071743" class="input-output-copier">Copy</div></div> <pre id="id0019654425752322746">7<br>car<br>care<br>careful<br>carefully<br>becarefuldontforgetsomething<br>otherwiseyouwillbehacked<br>goodluck<br></pre></div> <div class="output"> <div class="title">Output<div title="Copy" data-clipboard-target="#id0048188148367915673" id="id0007533705205471852" class="input-output-copier">Copy</div></div> <pre id="id0048188148367915673">acbdefhijklmnogpqrstuvwxyz<br></pre></div></div></div></div> |
| 4 | + |
| 5 | +## Solution 1. Topological Sort (BFS) |
| 6 | + |
| 7 | +```cpp |
| 8 | +#include <cstdio> |
| 9 | +#include <cstdlib> |
| 10 | +#include <cstring> |
| 11 | +#include <iostream> |
| 12 | +#include <vector> |
| 13 | +#include <string> |
| 14 | +#include <map> |
| 15 | +#include <unordered_map> |
| 16 | +#include <set> |
| 17 | +#include <stack> |
| 18 | +#include <queue> |
| 19 | +#include <unordered_set> |
| 20 | +#include <algorithm> |
| 21 | +using namespace std; |
| 22 | +#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0) |
| 23 | +#define PRINTCASE printf("Case #%d: ",case_n++) |
| 24 | +#define PRINTCASE_ printf("Case #%d:\n",case_n++) |
| 25 | +#define RD(a) scanf("%d", &(a)) |
| 26 | +#define RDD(a, b) scanf("%d%d", &(a), &(b)) |
| 27 | +#define PD(a) printf("%d", (a)) |
| 28 | +#define PD_(a) printf("%d\n", (a)) |
| 29 | +#define REP(i,s,t) for(int i=(s);i<(t);i++) |
| 30 | + |
| 31 | +string solve(int N, vector<string> &A) { |
| 32 | + vector<unordered_set<int>> G(26); |
| 33 | + for (int i = 1; i < N; ++i) { |
| 34 | + int j = 0; |
| 35 | + auto &a = A[i - 1], &b = A[i]; |
| 36 | + for (; j < min(a.size(), b.size()); ++j) { |
| 37 | + if (a[j] == b[j]) continue; |
| 38 | + G[a[j] - 'a'].insert(b[j] - 'a'); |
| 39 | + break; |
| 40 | + } |
| 41 | + if (j == min(a.size(), b.size()) && a.size() > b.size()) return "Impossible"; |
| 42 | + } |
| 43 | + string ans; |
| 44 | + int indegree[26] = {}; |
| 45 | + queue<int> q; |
| 46 | + for (int i = 0; i < 26; ++i) { |
| 47 | + for (int v : G[i]) indegree[v]++; |
| 48 | + } |
| 49 | + for (int i = 0; i < 26; ++i) { |
| 50 | + if (indegree[i] == 0) q.push(i); |
| 51 | + } |
| 52 | + while (q.size()) { |
| 53 | + int u = q.front(); |
| 54 | + q.pop(); |
| 55 | + ans.push_back('a' + u); |
| 56 | + for (int v : G[u]) { |
| 57 | + if (--indegree[v] == 0) q.push(v); |
| 58 | + } |
| 59 | + } |
| 60 | + return ans.size() == 26 ? ans : "Impossible"; |
| 61 | +} |
| 62 | + |
| 63 | +int main() { |
| 64 | + freopen("in", "r", stdin); |
| 65 | + freopen("out", "w", stdout); |
| 66 | + CASET { |
| 67 | + int N; |
| 68 | + RD(N); |
| 69 | + vector<string> A(N); |
| 70 | + REP(i, 0, N) { |
| 71 | + cin >> A[i]; |
| 72 | + } |
| 73 | + PRINTCASE; |
| 74 | + cout << solve(N, A) << endl; |
| 75 | + } |
| 76 | + return 0; |
| 77 | +} |
| 78 | +``` |
| 79 | +
|
| 80 | +## Solution 2. Topological Sort (DFS) |
| 81 | +
|
| 82 | +```cpp |
| 83 | +#include <cstdio> |
| 84 | +#include <cstdlib> |
| 85 | +#include <cstring> |
| 86 | +#include <iostream> |
| 87 | +#include <vector> |
| 88 | +#include <string> |
| 89 | +#include <map> |
| 90 | +#include <unordered_map> |
| 91 | +#include <set> |
| 92 | +#include <stack> |
| 93 | +#include <queue> |
| 94 | +#include <unordered_set> |
| 95 | +#include <algorithm> |
| 96 | +using namespace std; |
| 97 | +#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0) |
| 98 | +#define PRINTCASE printf("Case #%d: ",case_n++) |
| 99 | +#define PRINTCASE_ printf("Case #%d:\n",case_n++) |
| 100 | +#define RD(a) scanf("%d", &(a)) |
| 101 | +#define RDD(a, b) scanf("%d%d", &(a), &(b)) |
| 102 | +#define PD(a) printf("%d", (a)) |
| 103 | +#define PD_(a) printf("%d\n", (a)) |
| 104 | +#define REP(i,s,t) for(int i=(s);i<(t);i++) |
| 105 | +
|
| 106 | +vector<int> state; |
| 107 | +string ans; |
| 108 | +vector<unordered_set<int>> G; |
| 109 | +bool dfs(int u) { |
| 110 | + if (state[u]) return state[u] == 1; |
| 111 | + state[u] = -1; |
| 112 | + for (int v : G[u]) { |
| 113 | + if (!dfs(v)) return false; |
| 114 | + } |
| 115 | + state[u] = 1; |
| 116 | + ans.push_back('a' + u); |
| 117 | + return true; |
| 118 | +} |
| 119 | +string solve(int N, vector<string> &A) { |
| 120 | + G.assign(26, {}); |
| 121 | + ans.clear(); |
| 122 | + state.assign(26, 0); |
| 123 | + for (int i = 1; i < N; ++i) { |
| 124 | + int j = 0; |
| 125 | + auto &a = A[i - 1], &b = A[i]; |
| 126 | + for (; j < min(a.size(), b.size()); ++j) { |
| 127 | + if (a[j] == b[j]) continue; |
| 128 | + G[a[j] - 'a'].insert(b[j] - 'a'); |
| 129 | + break; |
| 130 | + } |
| 131 | + if (j == min(a.size(), b.size()) && a.size() > b.size()) return "Impossible"; |
| 132 | + } |
| 133 | + for (int i = 0; i < 26; ++i) { |
| 134 | + if (state[i]) continue; |
| 135 | + if (!dfs(i)) return "Impossible"; |
| 136 | + } |
| 137 | + reverse(ans.begin(), ans.end()); |
| 138 | + return ans; |
| 139 | +} |
| 140 | +
|
| 141 | +int main() { |
| 142 | + freopen("in", "r", stdin); |
| 143 | + freopen("out", "w", stdout); |
| 144 | + CASET { |
| 145 | + int N; |
| 146 | + RD(N); |
| 147 | + vector<string> A(N); |
| 148 | + REP(i, 0, N) { |
| 149 | + cin >> A[i]; |
| 150 | + } |
| 151 | + PRINTCASE; |
| 152 | + cout << solve(N, A) << endl; |
| 153 | + } |
| 154 | + return 0; |
| 155 | +} |
| 156 | +``` |
0 commit comments