結果
| 問題 |
No.470 Inverse S+T Problem
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-12-30 10:16:35 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,653 bytes |
| コンパイル時間 | 2,205 ms |
| コンパイル使用メモリ | 182,844 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-12-22 13:39:53 |
| 合計ジャッジ時間 | 3,116 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 WA * 3 |
| other | AC * 12 WA * 15 |
ソースコード
#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;
}