版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/88659251
【题目链接】
【思路要点】
- 将每一种单词的前,后方抽象为一个点,相邻的位置中间连边,搜索所有联通块即可。
- 时间复杂度 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, tot, num[MAXN]; string reals[MAXN]; map <string, int> home; bool stop[MAXN], comma[MAXN]; bool Front[MAXN], Back[MAXN]; vector <int> bf[MAXN], fb[MAXN]; void workf(int pos); void workb(int pos) { if (Back[pos]) return; Back[pos] = true; for (auto x : bf[pos]) workf(x); } void workf(int pos) { if (Front[pos]) return; Front[pos] = true; for (auto x : fb[pos]) workb(x); } int main() { string tmp; while (cin >> tmp) { n++; if (tmp.back() == '.') { tmp.pop_back(); stop[n] = true; } if (tmp.back() == ',') { tmp.pop_back(); comma[n] = true; } if (!home.count(tmp)) { home[tmp] = ++tot; reals[tot] = tmp; } num[n] = home[tmp]; } for (int i = 1; i <= n - 1; i++) if (!stop[i]) { bf[num[i]].push_back(num[i + 1]); fb[num[i + 1]].push_back(num[i]); } for (int i = 1; i <= n - 1; i++) if (comma[i]) { workb(num[i]); workf(num[i + 1]); } for (int i = 1; i <= n; i++) { cout << reals[num[i]]; if (stop[i]) cout << '.'; else if (Back[num[i]]) cout << ','; cout << ' '; } return 0; }