QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#780727 | #9802. Light Up the Grid | aYi_7# | TL | 11ms | 3848kb | C++17 | 5.9kb | 2024-11-25 12:49:53 | 2024-11-25 12:49:54 |
Judging History
answer
#include <bits/stdc++.h>
#define int long long
std::map<std::string, int> ans;
std::vector<std::bitset<4>> op_1(std::bitset<4> s) {
std::vector<std::bitset<4>> res;
for (int i = 0; i < 4; i++) {
s.flip(i);
res.emplace_back(s);
s.flip(i);
}
return res;
}
std::vector<std::bitset<4>> op_2(std::bitset<4> s) {
std::vector<std::bitset<4>> res;
s.flip(0), s.flip(1);
res.emplace_back(s);
s.flip(0), s.flip(1);
s.flip(2), s.flip(3);
res.emplace_back(s);
return res;
}
std::vector<std::bitset<4>> op_3(std::bitset<4> s) {
std::vector<std::bitset<4>> res;
s.flip(0), s.flip(2);
res.emplace_back(s);
s.flip(0), s.flip(2);
s.flip(1), s.flip(3);
res.emplace_back(s);
return res;
}
std::vector<std::bitset<4>> op_4(std::bitset<4> s) {
std::vector<std::bitset<4>> res;
s.flip();
res.emplace_back(s);
return res;
}
struct node {
std::bitset<16 * 4> sta;
std::vector<std::bitset<4>> a;
bool operator<(const node& A) const {
return sta.to_string() < A.sta.to_string();
}
};
int dij(std::vector<int>& p, std::map<node, int>& dis, node& st, int m) {
std::priority_queue<std::pair<int, node>, std::vector<std::pair<int, node>>,
std::greater<std::pair<int, node>>>
q;
dis[st] = 0;
bool tag = true;
q.push({0, st});
while (!q.empty()) {
auto [cost, now] = q.top();
// std::cout << cost << ' ' << now.sta.to_string() << '\n';
q.pop();
if(ans.count(now.sta.to_string()) != 0) return ans[st.sta.to_string()];
if (now.sta.all() && !tag) return cost;
std::vector<node> ne;
// op1
ne.assign(4, now);
for (int i = 0; i < m; i++) {
if (now.a[i].all() && !tag) continue;
auto t = op_1(now.a[i]);
for (int j = 0; j < t.size(); j++) {
ne[j].a[i] = t[j];
for (int k = 0; k < 4; ++k) {
ne[j].sta.set(i * 4 + k, t[j][k]);
}
}
}
for (int i = 0; i < ne.size(); i++) {
if (dis.count(ne[i]) == 0 || cost + p[0] < dis[ne[i]]) {
dis[ne[i]] = cost + p[0];
q.push({cost + p[0], ne[i]});
}
}
// op2
ne.assign(2, now);
for (int i = 0; i < m; i++) {
if (now.a[i].all() && !tag) continue;
auto t = op_2(now.a[i]);
for (int j = 0; j < t.size(); j++) {
ne[j].a[i] = t[j];
for (int k = 0; k < 4; ++k) {
ne[j].sta.set(i * 4 + k, t[j][k]);
}
}
}
for (int i = 0; i < ne.size(); i++) {
if (dis.count(ne[i]) == 0 || cost + p[1] < dis[ne[i]]) {
dis[ne[i]] = cost + p[1];
q.push({cost + p[1], ne[i]});
}
}
// op3
ne.assign(2, now);
for (int i = 0; i < m; i++) {
if (now.a[i].all() && !tag) continue;
auto t = op_3(now.a[i]);
for (int j = 0; j < t.size(); j++) {
ne[j].a[i] = t[j];
for (int k = 0; k < 4; ++k) {
ne[j].sta.set(i * 4 + k, t[j][k]);
}
}
}
for (int i = 0; i < ne.size(); i++) {
if (dis.count(ne[i]) == 0 || cost + p[2] < dis[ne[i]]) {
dis[ne[i]] = cost + p[2];
q.push({cost + p[2], ne[i]});
}
}
// op4
ne.assign(1, now);
for (int i = 0; i < m; i++) {
if (now.a[i].all() && !tag) continue;
auto t = op_4(now.a[i]);
for (int j = 0; j < t.size(); j++) {
ne[j].a[i] = t[j];
for (int k = 0; k < 4; ++k) {
ne[j].sta.set(i * 4 + k, t[j][k]);
}
}
}
for (int i = 0; i < ne.size(); i++) {
if (dis.count(ne[i]) == 0 || cost + p[3] < dis[ne[i]]) {
dis[ne[i]] = cost + p[3];
q.push({cost + p[3], ne[i]});
}
}
if(tag) {
tag = false;
dis.erase(st);
}
}
return -1;
}
void solve(std::vector<int>& p) {
int m;
std::cin >> m;
std::map<node, int> dis;
node st;
for (int i = 0; i < m; i++) {
std::bitset<4> t;
std::vector<std::string> s(2);
for (int j = 0; j < 2; j++) {
std::cin >> s[j];
for (int k = 0; k < 2; k++) {
if (s[j][k] == '1') t.set(j * 2 + k);
}
}
st.a.emplace_back(t);
}
for (int i = m; i < 16; i++) {
for (int j = 0; j < 4; j++) {
st.sta.set(i * 4 + j);
}
}
std::sort(st.a.begin(), st.a.end(), [&](auto A, auto B) {
return A.to_string() < B.to_string();
});
for (int i = 0; i < m; i++) {
// std::cout << st.a[i].to_string() << '\n';
// if (st.a[i].all()) st.sta.set(i);
for (int j = 0; j < 4; j++) {
if (st.a[i][j]) st.sta.set(i * 4 + j);
}
}
// std::cout << st.sta.to_string() << '\n';
// std::cout << dij(p, dis, st, m) << '\n';
if(ans.count(st.sta.to_string()) == 0) ans[st.sta.to_string()] = dij(p, dis, st, m);
std::cout << ans[st.sta.to_string()] << '\n';
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::vector<int> p(4);
int t = 1;
std::cin >> t;
for (auto& i : p) std::cin >> i;
for (int i = 0; i < t; ++i) {
solve(p);
}
return 0;
}
/*
2 1000 100 10 1
4
10
00
01
00
00
10
00
01
1
11
11
1 1000 100 10 1
1
11
11
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 5ms
memory: 3628kb
input:
2 1000 100 10 1 4 10 00 01 00 00 10 00 01 1 11 11
output:
1121 2
result:
ok 2 number(s): "1121 2"
Test #2:
score: 0
Accepted
time: 11ms
memory: 3848kb
input:
2 1 1 1 1 4 10 00 01 00 00 10 00 01 1 11 11
output:
5 2
result:
ok 2 number(s): "5 2"
Test #3:
score: 0
Accepted
time: 1ms
memory: 3644kb
input:
1 1000000 1000000 1000000 1000000 1 11 11
output:
2000000
result:
ok 1 number(s): "2000000"
Test #4:
score: -100
Time Limit Exceeded
input:
10000 8 2 7 8 8 00 01 00 11 00 10 11 11 10 10 01 10 01 00 10 11 8 11 01 11 00 01 10 11 11 00 01 01 01 01 00 11 10 9 00 00 01 01 10 11 00 01 11 10 11 00 11 11 00 11 01 10 9 11 11 10 00 11 00 11 01 00 10 01 11 00 01 01 01 10 01 11 00 01 01 01 10 10 00 11 11 11 11 10 ...