QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#788868 | #6439. Cloud Retainer's Game | _LSA_# | AC ✓ | 900ms | 38096kb | C++20 | 3.3kb | 2024-11-27 18:34:57 | 2024-11-27 18:35:03 |
Judging History
answer
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
int H, n, m;
struct position {
int x, y;
bool operator<(const position& rhs) const { return x == rhs.x ? y < rhs.y : x < rhs.x; }
} p[N][2];
struct line {
int k, b;
bool operator<(const line& rhs) const { return k == rhs.k ? b < rhs.b : k < rhs.k; }
bool operator==(const line& rhs) const { return k == rhs.k && b == rhs.b; }
};
map<line,vector<pair<int,int> > > mp;
int f[N][2][2];
auto cmp = [](const pair<int,int>& lhs, const pair<int,int>& rhs){ return p[lhs.first][lhs.second] < p[rhs.first][rhs.second]; };
line line1(position pos){
if(pos.x < pos.y) return line{1, pos.y - pos.x};
int x = (pos.x - pos.y) % (H << 1);
if(x == 0) return line{1, 0};
if(x <= H) return line{0, x};
else return line{1, ((H << 1) - x)};
}
line line2(position pos){
int x = (pos.x + pos.y) % (H << 1);
if(x == 0) return line{1, 0};
if(x <= H) return line{0, x};
else return line{1, ((H << 1) - x)};
}
int dp(int i, int j, int k){// p[i][j], direction: k: line1(1) / line2(0)
if(f[i][j][k] != -1) return f[i][j][k];
if(j){// coin
line l;
if(k) l = line1(p[i][j]);
else l = line2(p[i][j]);
auto ite = upper_bound(mp[l].begin(), mp[l].end(), make_pair(i, j), cmp);
if(ite == mp[l].end()) return f[i][j][k] = 1;
if(line1(p[ite->first][ite->second]) == l) return f[i][j][k] = dp(ite->first, ite->second, 1) + 1;
else return f[i][j][k] = dp(ite->first, ite->second, 0) + 1;
}
else{// board
line l1, l2;
if(k) l1 = line1(p[i][j]), l2 = line2(p[i][j]);
else l1 = line2(p[i][j]), l2 = line1(p[i][j]);
auto ite1 = upper_bound(mp[l1].begin(), mp[l1].end(), make_pair(i, j), cmp);
auto ite2 = upper_bound(mp[l2].begin(), mp[l2].end(), make_pair(i, j), cmp);
f[i][j][k] = 0;
if(ite1 != mp[l1].end()){
if(line1(p[ite1->first][ite1->second]) == l1) f[i][j][k] = max(f[i][j][k], dp(ite1->first, ite1->second, 1));
else f[i][j][k] = max(f[i][j][k], dp(ite1->first, ite1->second, 0));
}
if(ite2 != mp[l2].end()){
if(line1(p[ite2->first][ite2->second]) == l2) f[i][j][k] = max(f[i][j][k], dp(ite2->first, ite2->second, 1));
else f[i][j][k] = max(f[i][j][k], dp(ite2->first, ite2->second, 0));
}
return f[i][j][k];
}
}
void solve(){
cin >> H >> n;
p[0][1] = {0, 0}; mp[{1, 0}].push_back(make_pair(0, 1));
for(int i=1;i<=n;i++){
cin >> p[i][0].x >> p[i][0].y;
mp[line1(p[i][0])].emplace_back(make_pair(i, 0));
mp[line2(p[i][0])].emplace_back(make_pair(i, 0));
}
cin >> m;
for(int i=1;i<=m;i++){
cin >> p[i][1].x >> p[i][1].y;
mp[line1(p[i][1])].emplace_back(make_pair(i, 1));
mp[line2(p[i][1])].emplace_back(make_pair(i, 1));
}
for(auto& i : mp) sort(i.second.begin(), i.second.end(), cmp);
for(int i=0;i<=max(n, m);i++){
for(int j=0;j<=1;j++) f[i][j][0] = f[i][j][1] = -1;
}
cout << (dp(0, 1, 1) - 1) << '\n';
mp.clear();
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t; cin >> t;
while(t--) solve();
return 0;
}
//开摆了几何题懒得写
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 5648kb
input:
2 4 3 1 1 2 2 6 2 4 3 1 3 3 5 1 7 3 3 1 4 2 3 1 1 6 2 9 1
output:
3 3
result:
ok 2 number(s): "3 3"
Test #2:
score: 0
Accepted
time: 386ms
memory: 22120kb
input:
5503 10 19 2 4 2 8 8 3 8 4 8 7 2 7 2 6 1 5 3 2 6 4 2 1 4 5 2 5 7 1 4 7 5 7 2 2 8 6 8 1 12 5 1 4 8 5 2 6 1 3 6 1 1 1 7 7 2 5 6 6 8 1 2 3 5 10 5 9 5 10 7 6 6 5 7 1 3 9 6 8 8 8 6 4 2 9 5 4 4 2 10 9 2 3 2 1 7 1 4 3 14 4 6 6 1 2 1 7 6 2 3 4 4 5 3 6 5 1 4 3 4 3 2 6 2 8 6 8 2 6 6 5 2 5 1 3 1 2 3 7 4 5 5 3 ...
output:
2 1 2 1 3 2 0 2 4 6 1 2 0 0 1 2 1 1 0 1 0 0 2 1 1 3 2 3 3 2 1 2 0 1 5 1 1 1 0 1 3 1 2 3 3 3 2 1 0 3 1 2 2 0 4 1 1 0 1 2 2 2 1 1 1 1 2 3 2 2 2 1 1 3 1 3 0 0 3 4 5 1 1 1 1 1 0 2 0 0 3 0 2 1 1 1 0 3 2 1 3 4 3 2 2 4 2 4 2 1 2 1 0 1 3 0 3 0 2 1 0 2 5 1 2 2 1 0 1 3 0 2 3 1 4 2 2 0 2 3 2 0 0 3 1 1 1 1 3 2 ...
result:
ok 5503 numbers
Test #3:
score: 0
Accepted
time: 900ms
memory: 38096kb
input:
54 83 1995 54 14 42 63 23 55 46 52 94 71 16 18 51 54 62 47 90 38 42 50 82 20 8 28 52 64 49 19 56 5 10 74 99 30 90 42 48 2 11 78 4 38 78 77 26 26 47 12 82 60 41 17 87 2 37 16 51 15 32 63 88 82 76 33 44 10 94 28 31 5 30 80 29 19 35 70 88 78 39 69 40 5 84 52 87 59 54 36 34 76 88 42 42 37 79 70 27 77 19...
output:
47 32 32 32 38 32 39 33 39 40 36 32 36 32 46 30 35 41 40 36 108 90 98 81 166 115 106 170 148 113 198 72 57 202 337 153 186 978 87 886 151 489 111 112 90 154 174 188 266 59 10210 1041 87 981
result:
ok 54 numbers