結果
| 問題 |
No.470 Inverse S+T Problem
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-12-29 21:32:41 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,525 bytes |
| コンパイル時間 | 2,336 ms |
| コンパイル使用メモリ | 185,344 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-12-22 13:39:33 |
| 合計ジャッジ時間 | 3,254 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 WA * 1 |
| other | AC * 17 WA * 10 |
ソースコード
#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 unionfind {
public:
vector<int> data;
unionfind(int size) : data(size, -1) { }
bool union_set(int x, int y) {
x = root(x); y = root(y);
if (x != y) {
if (data[y] < data[x]) swap(x, y);
data[x] += data[y]; data[y] = x;
}
return x != y;
}
bool find_set(int x, int y) {
return root(x) == root(y);
}
int root(int x) {
return data[x] < 0 ? x : data[x] = root(data[x]);
}
int size(int x) {
return -data[root(x)];
}
};
// http://www.prefield.com/algorithm/graph/strongly_connected_components.html
template <typename U_FIND>
void strongly_connected_components_dfs(const Graph &g, int v, U_FIND& result,
stack<int> &s, vector<bool> &flg,
vector<int> &low, vector<int> &num, int& count) {
low[v] = num[v] = count++;
s.push(v);
flg[v] = true;
for (int w : g.vertex_to[v]){
if (num[w] == 0) {
strongly_connected_components_dfs(g, w, result, s, flg, low, num, count);
low[v] = min(low[v], low[w]);
} else if (flg[w]){ // ?
low[v] = min(low[v], num[w]);
}
}
if (low[v] == num[v]) {
while (!s.empty()) {
int w = s.top(); s.pop();
flg[w] = false;
if (v == w) break;
result.union_set(v,w);
}
}
}
template <typename U_FIND>
void strongly_connected_components(const Graph& graph, U_FIND& result) {
int size = graph.n;
vector<int> num(size), low(size);
stack<int> s;
vector<bool> flg(size);
int count = 1;
for (int i=0; i<graph.n; i++){
if (num[i] == 0){
strongly_connected_components_dfs(graph,i,result,s,flg,low,num,count);
}
}
}
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;}
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));
}
// 結果にかかわらずresultはresizeされる
// result[0]は番兵.trueを入れておくと解を求めず終了.
bool solve(vector<bool>& result){
result.resize(n+1);
unionfind uf(graph.n);
strongly_connected_components(graph,uf);
int i;
for (i=1;i<=n;i++){
if (uf.find_set(i,i+n)){
return false;
}
}
if (!result.empty() && result[0]) return true;
for (i=1;i<=n;i++){
result[i] = (uf.root(i)>uf.root(i+n));
}
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 0:
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 1:
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 2:
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 3:
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++){
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;
}