結果

問題 No.470 Inverse S+T Problem
ユーザー maimai
提出日時 2016-12-30 10:16:35
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 5,653 bytes
コンパイル時間 1,725 ms
コンパイル使用メモリ 183,556 KB
実行使用メモリ 6,948 KB
最終ジャッジ日時 2024-06-01 22:48:00
合計ジャッジ時間 2,788 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 AC 1 ms
6,948 KB
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 AC 2 ms
6,944 KB
testcase_07 AC 2 ms
6,940 KB
testcase_08 AC 1 ms
6,944 KB
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 AC 1 ms
6,944 KB
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 AC 2 ms
6,940 KB
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 AC 1 ms
6,944 KB
testcase_25 AC 2 ms
6,948 KB
testcase_26 AC 2 ms
6,944 KB
testcase_27 AC 2 ms
6,940 KB
testcase_28 AC 1 ms
6,944 KB
testcase_29 AC 1 ms
6,940 KB
testcase_30 AC 2 ms
6,940 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>

using namespace std;
typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;

#define debugv(v) printf("L%d %s => ",__LINE__,#v);for(auto e:v){cout<<e<<" ";}cout<<endl;
#define debugm(m) printf("L%d %s is..\n",__LINE__,#m);for(auto v:m){for(auto e:v){cout<<e<<" ";}cout<<endl;}
#define debuga(m,w) printf("L%d %s is => ",__LINE__,#m);for(int x=0;x<(w);x++){cout<<(m)[x]<<" ";}cout<<endl;
#define debugaa(m,w,h) printf("L%d %s is..\n",__LINE__,#m);for(int y=0;y<(h);y++){for(int x=0;x<(w);x++){cout<<(m)[x][y]<<" ";}cout<<endl;}
#define debugaar(m,w,h) printf("L%d %s is..\n",__LINE__,#m);for(int y=0;y<(h);y++){for(int x=0;x<(w);x++){cout<<(m)[y][x]<<" ";}cout<<endl;}
#define ALL(v) (v).begin(),(v).end()
#define BIGINT 0x7FFFFFFF
#define E107 1000000007ll
void printbit(int u){if(u==0)cout<<0;else{int s=0,k=0;for(;0<u;u>>=1,k++)s=(s<<1)|(u&1);for(;0<k--;s>>=1)cout<<(s&1);}}

#define TIME chrono::system_clock::now()
#define MILLISEC(t) (chrono::duration_cast<chrono::milliseconds>(t).count())

template<typename T1,typename T2>
ostream& operator <<(ostream &o,const pair<T1,T2> p){o<<"("<<p.first<<":"<<p.second<<")";return o;}

class Graph{
public:
    const size_t n;
    vector<vector<int>> vertex_to;   // vector<set<int>>でも良いかもしれない?
    vector<vector<int>> vertex_from;
    
    Graph(size_t n):n(n),vertex_to(n),vertex_from(n){}
    
    void connect(int from, int to){
        vertex_to[from].emplace_back(to);
        vertex_from[to].emplace_back(from);
    }
    vector<int>& operator[](int v){
        return vertex_to[v];
    }
    void resize(size_t n){
        vertex_to.resize(n);
        vertex_from.resize(n);
    }

    size_t degree(int v){
        return vertex_to[v].size() + vertex_from[v].size();
    }
    size_t degree_in(int v){
        return vertex_from[v].size();
    }
    size_t degree_out(int v){
        return vertex_to[v].size();
    }
    void reverse_direction(){
        vertex_from.swap(vertex_to);
    }
};

class sat_2{
public:
    size_t n;
    Graph graph;
    
    sat_2(size_t n):n(n),graph(n*2+1){
    }
    
private:
    int _cv(int v){return 0<v ? v : -v+n;}
    int _rv(int v){return v<n ? v : -v+n;}
    
    // http://www.prefield.com/algorithm/misc/2-sat.html
    void _scc_dfs(int v, vector<int>& ord, vector<int> &num, int k){
        if (0 <= num[v]) return;
        num[v] = k;
        for (int to : graph.vertex_to[v]){
            _scc_dfs(to, ord, num, k);
        }
            
        ord.push_back(v);
    }
public:
    
    // 1 <= a <= n OR -1 >= a >= -n
    // 正ならばx_a,負ならばNOT x_aを表現.
    void emplace(int a,int b){
        // assert(a!=0 && b!=0);
        graph.connect(_cv(-a),_cv(b));
        graph.connect(_cv(-b),_cv(a));
    }
    
    // TODO:殆どコピペなので読み直し
    bool solve(vector<bool>& result){
        int i;
        vector<int> num(graph.n, -1), ord, dro;
        
        for (i=0; i<graph.n; i++){
            _scc_dfs(i, ord, num, i);
        }
            
        reverse(ord.begin(), ord.end());
        graph.reverse_direction();
        fill(num.begin(), num.end(), -1);
        
        i=0;for (int e : ord){
            _scc_dfs(e, dro, num, i++);
        }
            
        for (i=1; i<=n; i++){
            if (num[i] == num[i+n])
                return false;
        }
        
        result.resize(n+1);
        for (i=1; i<=n; i++){
            result[i] = (num[i] < num[i+n]);
            //printf("%d %d\n",num[i],num[i+n]);
        }
        
        graph.reverse_direction(); // 戻しておく
        return true;
    }
    
    // bool satisfied(){
    //     unionfind uf(graph.n);
    //     strongly_connected_components(graph,uf);
    //     
    //     for (int i=1;i<=n;i++){
    //         if (uf.find_set(i,i+n)){
    //             return false;
    //         }
    //     }
    //     return true;
    // }
    
};

int width,height;
int m,n;

string data[100];

void halt(){
    cout << "Impossible" << endl;
    exit(0);
}

bool check(int i,int j,int bit){
    switch(bit){
    case 0b00:
        if (data[i][0]==data[j][0] && data[i][1]==data[j][1]) return false;
        if (data[i][2]==data[j][2]) return false;
        return true;
    case 0b01:
        if (data[i][0]==data[j][1] && data[i][1]==data[j][2]) return false;
        if (data[i][2]==data[j][0]) return false;
        return true;
    case 0b10:
        if (data[i][1]==data[j][0] && data[i][2]==data[j][1]) return false;
        if (data[i][0]==data[j][2]) return false;
        return true;
    case 0b11:
        if (data[i][1]==data[j][1] && data[i][2]==data[j][2]) return false;
        if (data[i][0]==data[j][0]) return false;
        return true;
    }
    abort();
}

int main(){
    int i,j,k;
    int x,y,a,b;
    
    cin >> n;
    if (52 < n) halt();
    
    cin.ignore();
    for (i=1;i<=n;i++){
        cin >> data[i];
    }
    
    sat_2 sat(n);
    for (i=1;i<=n-1;i++){
        for (j=i+1;j<=n;j++){
            if (!check(i,j,0b00))
                sat.emplace(i,j);
            if (!check(i,j,0b01))
                sat.emplace(i,-j);
            if (!check(i,j,0b10))
                sat.emplace(-i,j);
            if (!check(i,j,0b11))
                sat.emplace(-i,-j);
        }
    }
    vector<bool> result;
    if (!sat.solve(result)) halt();
    
    for (i=1;i<=n;i++){
        cout << result[i];
        if (result[i]){
            printf("%c%c %c\n",data[i][0],data[i][1],data[i][2]);
        }else{
            printf("%c %c%c\n",data[i][0],data[i][1],data[i][2]);
        }
    }
    
    return 0;
}
0