/// no time to waste
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define eb emplace_back
#define pii pair <int, int>
#define pli pair <ll, int>
#define fi first
#define se second
#define all(ac) ac.begin(), ac.end()
#define MASK(x) (1 << x)
#define ub(i, j) ((i >> j) & 1)
#define FBIT(x) (MASK(x) - 1)
#define FLIP(x, y) (FBIT(x) ^ y)
#define ii make_pair
#define int128 __int128_t
struct Vec {
ll x, y, z;
int id;
};
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
#define task "tet"
if(fopen(task".inp", "r")) {
freopen(task".inp", "r", stdin);
freopen(task".out", "w", stdout);
}
int n;
ll X, Y, Z;
cin >> n >> X >> Y >> Z;
vector<Vec> v(n);
// Nhận diện subtask 1 chiều (Quy hoạch động)
bool is1D_X = (Y == 0 && Z == 0);
bool is1D_Y = (X == 0 && Z == 0);
bool is1D_Z = (X == 0 && Y == 0);
for (int i = 0; i < n; i++) {
cin >> v[i].x >> v[i].y >> v[i].z;
v[i].id = i;
if (v[i].y != 0 || v[i].z != 0) is1D_X = false;
if (v[i].x != 0 || v[i].z != 0) is1D_Y = false;
if (v[i].x != 0 || v[i].y != 0) is1D_Z = false;
}
string ans(n, '0');
// Giải bằng Knapsack + Bitset cho các test 1D
if (is1D_X) {
vector<bitset<1000005>> dp(n + 1);
dp[0][0] = 1;
for (int i = 0; i < n; i++) dp[i + 1] = dp[i] | (dp[i] << v[i].x);
ll cur = X;
for (int i = n - 1; i >= 0; i--) {
if (cur >= v[i].x && dp[i][cur - v[i].x]) {
ans[v[i].id] = '1';
cur -= v[i].x;
}
}
cout << ans << "\n";
return 0;
}
if (is1D_Y) {
vector<bitset<1000005>> dp(n + 1);
dp[0][0] = 1;
for (int i = 0; i < n; i++) dp[i + 1] = dp[i] | (dp[i] << v[i].y);
ll cur = Y;
for (int i = n - 1; i >= 0; i--) {
if (cur >= v[i].y && dp[i][cur - v[i].y]) {
ans[v[i].id] = '1';
cur -= v[i].y;
}
}
cout << ans << "\n";
return 0;
}
if (is1D_Z) {
vector<bitset<1000005>> dp(n + 1);
dp[0][0] = 1;
for (int i = 0; i < n; i++) dp[i + 1] = dp[i] | (dp[i] << v[i].z);
ll cur = Z;
for (int i = n - 1; i >= 0; i--) {
if (cur >= v[i].z && dp[i][cur - v[i].z]) {
ans[v[i].id] = '1';
cur -= v[i].z;
}
}
cout << ans << "\n";
return 0;
}
// Giải bằng Backtracking + Pruning cho trường hợp 3D tổng quát
sort(v.begin(), v.end(), [](const Vec& a, const Vec& b) {
return a.x + a.y + a.z > b.x + b.y + b.z;
});
vector<ll> sufX(n + 1, 0), sufY(n + 1, 0), sufZ(n + 1, 0);
for (int i = n - 1; i >= 0; i--) {
sufX[i] = sufX[i + 1] + v[i].x;
sufY[i] = sufY[i + 1] + v[i].y;
sufZ[i] = sufZ[i + 1] + v[i].z;
}
bool found = false;
auto dfs = [&](auto& self, int idx, ll cx, ll cy, ll cz) -> void {
if (found) return;
if (cx == X && cy == Y && cz == Z) {
found = true;
return;
}
if (idx == n) return;
// Nhánh cận: Nếu đã vượt quá mục tiêu
if (cx > X || cy > Y || cz > Z) return;
// Nhánh cận: Nếu cộng tất cả phần tử còn lại vẫn không đủ mục tiêu
if (cx + sufX[idx] < X || cy + sufY[idx] < Y || cz + sufZ[idx] < Z) return;
ans[v[idx].id] = '1';
self(self, idx + 1, cx + v[idx].x, cy + v[idx].y, cz + v[idx].z);
if (found) return;
ans[v[idx].id] = '0';
self(self, idx + 1, cx, cy, cz);
};
dfs(dfs, 0, 0, 0, 0);
cout << ans << "\n";
return 0;
}
Ly8vIG5vIHRpbWUgdG8gd2FzdGUKI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgbGwgbG9uZyBsb25nCiNkZWZpbmUgZWIgZW1wbGFjZV9iYWNrCiNkZWZpbmUgcGlpIHBhaXIgPGludCwgaW50PgojZGVmaW5lIHBsaSBwYWlyIDxsbCwgaW50PgojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2Ugc2Vjb25kCiNkZWZpbmUgYWxsKGFjKSBhYy5iZWdpbigpLCBhYy5lbmQoKQojZGVmaW5lIE1BU0soeCkgKDEgPDwgeCkKI2RlZmluZSB1YihpLCBqKSAoKGkgPj4gaikgJiAxKQojZGVmaW5lIEZCSVQoeCkgKE1BU0soeCkgLSAxKQojZGVmaW5lIEZMSVAoeCwgeSkgKEZCSVQoeCkgXiB5KQojZGVmaW5lIGlpIG1ha2VfcGFpcgojZGVmaW5lIGludDEyOCBfX2ludDEyOF90CgpzdHJ1Y3QgVmVjIHsKICAgIGxsIHgsIHksIHo7CiAgICBpbnQgaWQ7Cn07CgppbnQzMl90IG1haW4oKSB7CiAgICBpb3M6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgICBjaW4udGllKDApLCBjb3V0LnRpZSgwKTsKICAgICNkZWZpbmUgdGFzayAidGV0IgogICAgaWYoZm9wZW4odGFzayIuaW5wIiwgInIiKSkgewogICAgICAgIGZyZW9wZW4odGFzayIuaW5wIiwgInIiLCBzdGRpbik7CiAgICAgICAgZnJlb3Blbih0YXNrIi5vdXQiLCAidyIsIHN0ZG91dCk7CiAgICB9CgogICAgaW50IG47CiAgICBsbCBYLCBZLCBaOwogICAgY2luID4+IG4gPj4gWCA+PiBZID4+IFo7CgogICAgdmVjdG9yPFZlYz4gdihuKTsKICAgIC8vIE5o4bqtbiBkaeG7h24gc3VidGFzayAxIGNoaeG7gXUgKFF1eSBob+G6oWNoIMSR4buZbmcpCiAgICBib29sIGlzMURfWCA9IChZID09IDAgJiYgWiA9PSAwKTsKICAgIGJvb2wgaXMxRF9ZID0gKFggPT0gMCAmJiBaID09IDApOwogICAgYm9vbCBpczFEX1ogPSAoWCA9PSAwICYmIFkgPT0gMCk7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICBjaW4gPj4gdltpXS54ID4+IHZbaV0ueSA+PiB2W2ldLno7CiAgICAgICAgdltpXS5pZCA9IGk7CiAgICAgICAgaWYgKHZbaV0ueSAhPSAwIHx8IHZbaV0ueiAhPSAwKSBpczFEX1ggPSBmYWxzZTsKICAgICAgICBpZiAodltpXS54ICE9IDAgfHwgdltpXS56ICE9IDApIGlzMURfWSA9IGZhbHNlOwogICAgICAgIGlmICh2W2ldLnggIT0gMCB8fCB2W2ldLnkgIT0gMCkgaXMxRF9aID0gZmFsc2U7CiAgICB9CgogICAgc3RyaW5nIGFucyhuLCAnMCcpOwoKICAgIC8vIEdp4bqjaSBi4bqxbmcgS25hcHNhY2sgKyBCaXRzZXQgY2hvIGPDoWMgdGVzdCAxRAogICAgaWYgKGlzMURfWCkgewogICAgICAgIHZlY3RvcjxiaXRzZXQ8MTAwMDAwNT4+IGRwKG4gKyAxKTsKICAgICAgICBkcFswXVswXSA9IDE7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIGRwW2kgKyAxXSA9IGRwW2ldIHwgKGRwW2ldIDw8IHZbaV0ueCk7CiAgICAgICAgbGwgY3VyID0gWDsKICAgICAgICBmb3IgKGludCBpID0gbiAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgICAgIGlmIChjdXIgPj0gdltpXS54ICYmIGRwW2ldW2N1ciAtIHZbaV0ueF0pIHsKICAgICAgICAgICAgICAgIGFuc1t2W2ldLmlkXSA9ICcxJzsKICAgICAgICAgICAgICAgIGN1ciAtPSB2W2ldLng7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY291dCA8PCBhbnMgPDwgIlxuIjsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoaXMxRF9ZKSB7CiAgICAgICAgdmVjdG9yPGJpdHNldDwxMDAwMDA1Pj4gZHAobiArIDEpOwogICAgICAgIGRwWzBdWzBdID0gMTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgZHBbaSArIDFdID0gZHBbaV0gfCAoZHBbaV0gPDwgdltpXS55KTsKICAgICAgICBsbCBjdXIgPSBZOwogICAgICAgIGZvciAoaW50IGkgPSBuIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgaWYgKGN1ciA+PSB2W2ldLnkgJiYgZHBbaV1bY3VyIC0gdltpXS55XSkgewogICAgICAgICAgICAgICAgYW5zW3ZbaV0uaWRdID0gJzEnOwogICAgICAgICAgICAgICAgY3VyIC09IHZbaV0ueTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb3V0IDw8IGFucyA8PCAiXG4iOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChpczFEX1opIHsKICAgICAgICB2ZWN0b3I8Yml0c2V0PDEwMDAwMDU+PiBkcChuICsgMSk7CiAgICAgICAgZHBbMF1bMF0gPSAxOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSBkcFtpICsgMV0gPSBkcFtpXSB8IChkcFtpXSA8PCB2W2ldLnopOwogICAgICAgIGxsIGN1ciA9IFo7CiAgICAgICAgZm9yIChpbnQgaSA9IG4gLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgICBpZiAoY3VyID49IHZbaV0ueiAmJiBkcFtpXVtjdXIgLSB2W2ldLnpdKSB7CiAgICAgICAgICAgICAgICBhbnNbdltpXS5pZF0gPSAnMSc7CiAgICAgICAgICAgICAgICBjdXIgLT0gdltpXS56OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvdXQgPDwgYW5zIDw8ICJcbiI7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLy8gR2nhuqNpIGLhurFuZyBCYWNrdHJhY2tpbmcgKyBQcnVuaW5nIGNobyB0csaw4budbmcgaOG7o3AgM0QgdOG7lW5nIHF1w6F0CiAgICBzb3J0KHYuYmVnaW4oKSwgdi5lbmQoKSwgW10oY29uc3QgVmVjJiBhLCBjb25zdCBWZWMmIGIpIHsKICAgICAgICByZXR1cm4gYS54ICsgYS55ICsgYS56ID4gYi54ICsgYi55ICsgYi56OwogICAgfSk7CgogICAgdmVjdG9yPGxsPiBzdWZYKG4gKyAxLCAwKSwgc3VmWShuICsgMSwgMCksIHN1ZloobiArIDEsIDApOwogICAgZm9yIChpbnQgaSA9IG4gLSAxOyBpID49IDA7IGktLSkgewogICAgICAgIHN1ZlhbaV0gPSBzdWZYW2kgKyAxXSArIHZbaV0ueDsKICAgICAgICBzdWZZW2ldID0gc3VmWVtpICsgMV0gKyB2W2ldLnk7CiAgICAgICAgc3VmWltpXSA9IHN1ZlpbaSArIDFdICsgdltpXS56OwogICAgfQoKICAgIGJvb2wgZm91bmQgPSBmYWxzZTsKICAgIGF1dG8gZGZzID0gWyZdKGF1dG8mIHNlbGYsIGludCBpZHgsIGxsIGN4LCBsbCBjeSwgbGwgY3opIC0+IHZvaWQgewogICAgICAgIGlmIChmb3VuZCkgcmV0dXJuOwogICAgICAgIGlmIChjeCA9PSBYICYmIGN5ID09IFkgJiYgY3ogPT0gWikgewogICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKGlkeCA9PSBuKSByZXR1cm47CiAgICAgICAgLy8gTmjDoW5oIGPhuq1uOiBO4bq/dSDEkcOjIHbGsOG7o3QgcXXDoSBt4bulYyB0acOqdQogICAgICAgIGlmIChjeCA+IFggfHwgY3kgPiBZIHx8IGN6ID4gWikgcmV0dXJuOwogICAgICAgIC8vIE5ow6FuaCBj4bqtbjogTuG6v3UgY+G7mW5nIHThuqV0IGPhuqMgcGjhuqduIHThu60gY8OybiBs4bqhaSB24bqrbiBraMO0bmcgxJHhu6cgbeG7pWMgdGnDqnUKICAgICAgICBpZiAoY3ggKyBzdWZYW2lkeF0gPCBYIHx8IGN5ICsgc3VmWVtpZHhdIDwgWSB8fCBjeiArIHN1ZlpbaWR4XSA8IFopIHJldHVybjsKCiAgICAgICAgYW5zW3ZbaWR4XS5pZF0gPSAnMSc7CiAgICAgICAgc2VsZihzZWxmLCBpZHggKyAxLCBjeCArIHZbaWR4XS54LCBjeSArIHZbaWR4XS55LCBjeiArIHZbaWR4XS56KTsKICAgICAgICBpZiAoZm91bmQpIHJldHVybjsKCiAgICAgICAgYW5zW3ZbaWR4XS5pZF0gPSAnMCc7CiAgICAgICAgc2VsZihzZWxmLCBpZHggKyAxLCBjeCwgY3ksIGN6KTsKICAgIH07CgogICAgZGZzKGRmcywgMCwgMCwgMCwgMCk7CgogICAgY291dCA8PCBhbnMgPDwgIlxuIjsKICAgIAogICAgcmV0dXJuIDA7Cn0=