提出詳細


ソースコード

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

template<typename T1, typename T2>
inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using Int = long long int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007


//edit
struct SCC {
    int V;
    vector<vector<int> > G;//グラフの隣接リスト表現
    vector<vector<int> > rG;//変の向きを逆にしたグラフ
    vector<int> vs;//帰りがけ順の並び
    vector<bool> used;//既に調べたか
    vector<int> cmp;//属する共連結成分のトポロジカル順序

    SCC(int v) {
        V = v;
        G.resize(V);
        rG.resize(V);
        used.resize(V);
        cmp.resize(V);
    }

    /**
     * 辺を貼る
     * @param from 辺の元
     * @param to 辺の先
     */
    void add_edge(int from, int to) {
        G[from].push_back(to);
        rG[to].push_back(from);
    }

    void dfs(int v) {
        used[v] = true;
        for (int i = 0; i < G[v].size(); i++) {
            if (!used[G[v][i]]) dfs(G[v][i]);
        }
        vs.push_back(v);
    }


    void rdfs(int v, int k) {
        used[v] = true;
        cmp[v] = k;
        for (int i = 0; i < rG[v].size(); i++) {
            if (!used[rG[v][i]]) rdfs(rG[v][i], k);
        }
    }

    int scc() {
        fill(used.begin(), used.end(), false);
        vs.clear();
        for (int v = 0; v < V; v++) {
            if (!used[v]) dfs(v);
        }
        fill(used.begin(), used.end(), false);
        int k = 0;
        for (int i = vs.size() - 1; i >= 0; i--) {
            if (!used[vs[i]]) rdfs(vs[i], k++);
        }
        return k;
    }
};

class Solve {
public:
    void solve() {
        Int N;
        cin >> N;
        vector<string> vs(N);
        SCC scc(26);

        for (int i = 0; i < N; ++i) cin >> vs[i];

        vector<Int> in(26), out(26);
        set<Int> st;
        for (auto e : vs) {
            in[e.front() - 'a']++;
            out[e.back() - 'a']++;
            scc.add_edge(e.back() - 'a', e.front() - 'a');
            st.insert(e.back() - 'a');
            st.insert(e.front() - 'a');
        }

        int k = scc.scc();

        vector<Int> diff(26);
        for (int i = 0; i < 26; ++i) {
            diff[i] = out[i] - in[i];
        }

        if (*min_element(all(diff)) == 0 && *max_element(all(diff)) == 0) {

            for (auto e : st) {
                if (scc.cmp[e] != scc.cmp[*st.begin()]) {
                    cout << "NG" << endl;
                    return;
                }
            }
            cout << "OK" << endl;
            return;
        }

        if (*min_element(all(diff)) < -1 || *max_element(all(diff)) > 1) {
            cout << "NG" << endl;
            return;
        }

        Int p = 0, m = 0;
        Int s, t;
        for (int i = 0; i < 26; ++i) {
            if (diff[i] == 1) {
                p++;
                s = i;
            }
            if (diff[i] == -1) {
                m--;
                t = i;
            }
        }

        if (p == 1 && m == 1 && scc.cmp[s] == 0 && scc.cmp[t] == 1) {
            cout << "OK" << endl;
            return;
        }
        cout << "NG" << endl;
        return;

    }
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    Int T;
    cin >> T;
    for (int i = 1; i <= T; ++i) {
        cout << "Case #" << i << ":" << endl;
        Solve().solve();
    }


    return 0;
}

提出情報

提出時間 2019-11-30 15:20:45
問題 K - ワードサークル
ユーザ名 nim_game
状態 正解
正解率 50/50
提出出力結果

テストケース情報

# 状態 詳細情報
テストケース 1 正解 詳細を見る
テストケース 2 正解 詳細を見る
テストケース 3 正解 詳細を見る
テストケース 4 正解 詳細を見る
テストケース 5 正解 詳細を見る
テストケース 6 正解 詳細を見る
テストケース 7 正解 詳細を見る
テストケース 8 正解 詳細を見る
テストケース 9 正解 詳細を見る
テストケース 10 正解 詳細を見る
テストケース 11 正解 詳細を見る
テストケース 12 正解 詳細を見る
テストケース 13 正解 詳細を見る
テストケース 14 正解 詳細を見る
テストケース 15 正解 詳細を見る
テストケース 16 正解 詳細を見る
テストケース 17 正解 詳細を見る
テストケース 18 正解 詳細を見る
テストケース 19 正解 詳細を見る
テストケース 20 正解 詳細を見る
テストケース 21 正解 詳細を見る
テストケース 22 正解 詳細を見る
テストケース 23 正解 詳細を見る
テストケース 24 正解 詳細を見る
テストケース 25 正解 詳細を見る
テストケース 26 正解 詳細を見る
テストケース 27 正解 詳細を見る
テストケース 28 正解 詳細を見る
テストケース 29 正解 詳細を見る
テストケース 30 正解 詳細を見る
テストケース 31 正解 詳細を見る
テストケース 32 正解 詳細を見る
テストケース 33 正解 詳細を見る
テストケース 34 正解 詳細を見る
テストケース 35 正解 詳細を見る
テストケース 36 正解 詳細を見る
テストケース 37 正解 詳細を見る
テストケース 38 正解 詳細を見る
テストケース 39 正解 詳細を見る
テストケース 40 正解 詳細を見る
テストケース 41 正解 詳細を見る
テストケース 42 正解 詳細を見る
テストケース 43 正解 詳細を見る
テストケース 44 正解 詳細を見る
テストケース 45 正解 詳細を見る
テストケース 46 正解 詳細を見る
テストケース 47 正解 詳細を見る
テストケース 48 正解 詳細を見る
テストケース 49 正解 詳細を見る
テストケース 50 正解 詳細を見る