#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <cstdint>
typedef int NType;
typedef std::vector<std::vector<NType>> DType;
DType Normalize(DType vec){
std::map<NType, NType> m;
NType n = 1;
for (auto& oo : vec){
for (auto& o : oo){
if (m[o] == 0)m[o] = n++;
o = m[o];
}
}
return vec;
}
bool ShowTatamiOne(DType& vec){
std::map<NType, NType> m;
NType n = 1;
m[0] = -1;
for (auto& oo : vec){
for (auto& o : oo){
if (m[o] == 0)m[o] = n++;
// std::cout << m[o] << ',';
std::cout << o << ',';
}
std::cout << std::endl;
}
return true;
}
DType CreateMass(int W, int H){
DType vec(H);
for (auto& o : vec)o.resize(W);
return vec;
}
bool IsFull(DType& vec){
for (auto& oo : vec){
for (auto& o : oo){
if (o == 0){
return false;
}
}
}
return true;
}
bool IsValid(DType& vec){
//empty
return true;//わかんなーい。
}
bool Paint(DType& d, int x, int y,volatile NType & N, bool IsRight,bool IsForce=false){
N++;
if (d.size() <= y)return false;
if (d[y].size() <= x)return false;
if (IsRight == true){
if (d[y].size() <= x + 1)return false;
if (IsForce == false){
if ((d[y][x] != 0 || d[y][x + 1] != 0)) return false;
}
d[y][x] = N;
d[y][x+1] = N;
}
else{
if (d.size() <= y + 1)return false;
if (IsForce == false){
if (d[y][x] != 0 || d[y + 1][x] != 0) return false;
}
d[y][x] = N;
d[y+1][x] = N;
}
return true;
}
bool Compair(DType& x, DType& y){
if (x.size() != y.size()) return false;
auto A = Normalize(x);
auto B = Normalize(y);
for (std::size_t i = 0; i < A.size(); i++){
if (A[i].size() != B[i].size()) return false;
for (std::size_t j = 0; j < A[i].size(); j++){
if (A[i][j] != B[i][j]) return false;
}
}
return true;
}
bool HogeRec(std::vector<DType>& R, DType& D, int x, int y,NType& N, bool IsRight = true){
DType& Dup = D;
if (Dup.size() <= y)return false;
if (Dup[y].size() <= x)return false;
bool F = Paint(Dup, x, y, N, IsRight);
if (F == false)return false;
HogeRec(R, Dup, x + 1, y, N);
HogeRec(R, Dup, x + 1, y, N, false);
HogeRec(R, Dup, x, y + 1, N);
HogeRec(R, Dup, x, y + 1, N, false);
/* */
if (IsFull(Dup) == true){
if (IsValid(Dup) == true){
R.push_back(Dup);
return true;
}
}
return true;
}
std::vector<DType> MakeHoge(int W, int H){
std::vector<DType> vec;
DType d;
NType N = 1000;//畳の色。表示時に正規化するんで、適当な数字で開始。小さすぎると正規化失敗する。Orz
for (int i = 0; i < H; i++){
for (int j = 0; j < W; j++){
d = CreateMass(W, H);
HogeRec(vec, d, i, j, N, true);
d = CreateMass(W, H);
HogeRec(vec, d, i, j, N, false);
}
}
for (std::size_t i = 0; i < vec.size(); i++){
for (std::size_t j = 0; j < vec.size(); j++){
if (i == j) continue;
if (Compair(vec[i], vec[j]) == true ){
vec.erase(vec.begin() + j);
i--;
break;
}
}
}
return vec;
}
bool ShowTatami(std::vector<DType>& vec){
for (auto& ooo : vec){
ShowTatamiOne(ooo);
std::cout << std::endl;
}
return true;
}
int main(){
auto R = MakeHoge(5, 6);
ShowTatami(R);
return true;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8Y3N0ZGludD4KCnR5cGVkZWYgaW50IE5UeXBlOwp0eXBlZGVmIHN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPE5UeXBlPj4gRFR5cGU7CgoKRFR5cGUgTm9ybWFsaXplKERUeXBlIHZlYyl7CglzdGQ6Om1hcDxOVHlwZSwgTlR5cGU+IG07CglOVHlwZSBuID0gMTsKCglmb3IgKGF1dG8mIG9vIDogdmVjKXsKCQlmb3IgKGF1dG8mIG8gOiBvbyl7CgkJCWlmIChtW29dID09IDApbVtvXSA9IG4rKzsKCQkJbyA9IG1bb107CgkJfQoJfQoKCXJldHVybiB2ZWM7Cn0KCmJvb2wgU2hvd1RhdGFtaU9uZShEVHlwZSYgdmVjKXsKCXN0ZDo6bWFwPE5UeXBlLCBOVHlwZT4gbTsKCU5UeXBlIG4gPSAxOwoKCW1bMF0gPSAtMTsKCglmb3IgKGF1dG8mIG9vIDogdmVjKXsKCQlmb3IgKGF1dG8mIG8gOiBvbyl7CgkJCWlmIChtW29dID09IDApbVtvXSA9IG4rKzsKLy8JCQlzdGQ6OmNvdXQgPDwgbVtvXSA8PCAnLCc7CgkJCXN0ZDo6Y291dCA8PCBvIDw8ICcsJzsKCQkJCgkJfQoJCXN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7Cgl9CgoJcmV0dXJuIHRydWU7Cn0KCkRUeXBlIENyZWF0ZU1hc3MoaW50IFcsIGludCBIKXsKCURUeXBlIHZlYyhIKTsKCglmb3IgKGF1dG8mIG8gOiB2ZWMpby5yZXNpemUoVyk7CgoJcmV0dXJuIHZlYzsKfQoKYm9vbCBJc0Z1bGwoRFR5cGUmIHZlYyl7Cglmb3IgKGF1dG8mIG9vIDogdmVjKXsKCQlmb3IgKGF1dG8mIG8gOiBvbyl7CgkJCWlmIChvID09IDApewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoJfQoJcmV0dXJuIHRydWU7Cn0KYm9vbCBJc1ZhbGlkKERUeXBlJiB2ZWMpewoJLy9lbXB0eQoJcmV0dXJuIHRydWU7Ly/jgo/jgYvjgpPjgarjg7zjgYTjgIIKfQoKYm9vbCBQYWludChEVHlwZSYgZCwgaW50IHgsIGludCB5LHZvbGF0aWxlIE5UeXBlICYgTiwgYm9vbCBJc1JpZ2h0LGJvb2wgSXNGb3JjZT1mYWxzZSl7CglOKys7CglpZiAoZC5zaXplKCkgPD0geSlyZXR1cm4gZmFsc2U7CQoJaWYgKGRbeV0uc2l6ZSgpIDw9IHgpcmV0dXJuIGZhbHNlOwoJaWYgKElzUmlnaHQgPT0gdHJ1ZSl7CgkJaWYgKGRbeV0uc2l6ZSgpIDw9IHggKyAxKXJldHVybiBmYWxzZTsKCQlpZiAoSXNGb3JjZSA9PSBmYWxzZSl7CgkJCWlmICgoZFt5XVt4XSAhPSAwIHx8IGRbeV1beCArIDFdICE9IDApKSByZXR1cm4gZmFsc2U7CgkJfQoJCWRbeV1beF0gPSBOOwoJCWRbeV1beCsxXSA9IE47Cgl9CgllbHNlewoJCWlmIChkLnNpemUoKSA8PSB5ICsgMSlyZXR1cm4gZmFsc2U7CgkJaWYgKElzRm9yY2UgPT0gZmFsc2UpewoJCQlpZiAoZFt5XVt4XSAhPSAwIHx8IGRbeSArIDFdW3hdICE9IDApIHJldHVybiBmYWxzZTsKCQl9CgkJZFt5XVt4XSA9IE47CgkJZFt5KzFdW3hdID0gTjsKCX0KCQoJcmV0dXJuIHRydWU7Cgp9Cgpib29sIENvbXBhaXIoRFR5cGUmIHgsIERUeXBlJiB5KXsKCglpZiAoeC5zaXplKCkgIT0geS5zaXplKCkpIHJldHVybiBmYWxzZTsKCWF1dG8gQSA9IE5vcm1hbGl6ZSh4KTsKCWF1dG8gQiA9IE5vcm1hbGl6ZSh5KTsKCglmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgQS5zaXplKCk7IGkrKyl7CgkJaWYgKEFbaV0uc2l6ZSgpICE9IEJbaV0uc2l6ZSgpKSByZXR1cm4gZmFsc2U7CgkJZm9yIChzdGQ6OnNpemVfdCBqID0gMDsgaiA8IEFbaV0uc2l6ZSgpOyBqKyspewoJCQlpZiAoQVtpXVtqXSAhPSBCW2ldW2pdKSByZXR1cm4gZmFsc2U7CgkJfQoJfQoKCXJldHVybiB0cnVlOwp9Cgpib29sIEhvZ2VSZWMoc3RkOjp2ZWN0b3I8RFR5cGU+JiBSLCBEVHlwZSYgRCwgaW50IHgsIGludCB5LE5UeXBlJiBOLCBib29sIElzUmlnaHQgPSB0cnVlKXsKCURUeXBlJiBEdXAgPSBEOwoKCWlmIChEdXAuc2l6ZSgpIDw9IHkpcmV0dXJuIGZhbHNlOwkKCWlmIChEdXBbeV0uc2l6ZSgpIDw9IHgpcmV0dXJuIGZhbHNlOwoJCglib29sIEYgPSBQYWludChEdXAsIHgsIHksIE4sIElzUmlnaHQpOwoJaWYgKEYgPT0gZmFsc2UpcmV0dXJuIGZhbHNlOwoKCUhvZ2VSZWMoUiwgRHVwLCB4ICsgMSwgeSwgTik7CglIb2dlUmVjKFIsIER1cCwgeCArIDEsIHksIE4sIGZhbHNlKTsKCUhvZ2VSZWMoUiwgRHVwLCB4LCB5ICsgMSwgTik7CglIb2dlUmVjKFIsIER1cCwgeCwgeSArIDEsIE4sIGZhbHNlKTsKCS8qICovCglpZiAoSXNGdWxsKER1cCkgPT0gdHJ1ZSl7CgkJaWYgKElzVmFsaWQoRHVwKSA9PSB0cnVlKXsKCQkJUi5wdXNoX2JhY2soRHVwKTsKCQkJcmV0dXJuIHRydWU7CgkJfQoJfQoJcmV0dXJuIHRydWU7Cn0KCnN0ZDo6dmVjdG9yPERUeXBlPiBNYWtlSG9nZShpbnQgVywgaW50IEgpewoJc3RkOjp2ZWN0b3I8RFR5cGU+IHZlYzsKCURUeXBlIGQ7CglOVHlwZSBOID0gMTAwMDsvL+eVs+OBruiJsuOAguihqOekuuaZguOBq+ato+imj+WMluOBmeOCi+OCk+OBp+OAgemBqeW9k+OBquaVsOWtl+OBp+mWi+Wni+OAguWwj+OBleOBmeOBjuOCi+OBqOato+imj+WMluWkseaVl+OBmeOCi+OAgk9yegoKCWZvciAoaW50IGkgPSAwOyBpIDwgSDsgaSsrKXsKCQlmb3IgKGludCBqID0gMDsgaiA8IFc7IGorKyl7CgkJCWQgPSBDcmVhdGVNYXNzKFcsIEgpOwoJCQlIb2dlUmVjKHZlYywgZCwgaSwgaiwgTiwgdHJ1ZSk7CgkJCWQgPSBDcmVhdGVNYXNzKFcsIEgpOwoJCQlIb2dlUmVjKHZlYywgZCwgaSwgaiwgTiwgZmFsc2UpOwoJCX0KCX0KCgkKCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCB2ZWMuc2l6ZSgpOyBpKyspewoJCWZvciAoc3RkOjpzaXplX3QgaiA9IDA7IGogPCB2ZWMuc2l6ZSgpOyBqKyspewoJCQlpZiAoaSA9PSBqKSBjb250aW51ZTsKCQkJaWYgKENvbXBhaXIodmVjW2ldLCB2ZWNbal0pID09IHRydWUgKXsKCQkJCXZlYy5lcmFzZSh2ZWMuYmVnaW4oKSArIGopOwoJCQkJaS0tOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIHZlYzsKfQoKYm9vbCBTaG93VGF0YW1pKHN0ZDo6dmVjdG9yPERUeXBlPiYgdmVjKXsKCglmb3IgKGF1dG8mIG9vbyA6IHZlYyl7CgkJU2hvd1RhdGFtaU9uZShvb28pOwoJCXN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7Cgl9CgoJcmV0dXJuIHRydWU7Cn0KCmludCBtYWluKCl7CgoJYXV0byBSID0gTWFrZUhvZ2UoNSwgNik7CglTaG93VGF0YW1pKFIpOwoJCglyZXR1cm4gdHJ1ZTsKfQ==