微信号:13674033087
我的代码:(WA 20)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int t, n, m, l, v, p[N], itk;
bool del[N];
struct car {
int d, v, a;
} f[N];
struct range {
bool zk, yk;
double s, t;
} k[N];
bool small(int x, range itr) {
if(itr.zk) return x<=itr.s;
return x<itr.s;
}
bool check(int x, range itr) {
if(itr.zk&&itr.yk) return (itr.s<x)&&(x<itr.t);// ( , )
if((!itr.zk)&&(!itr.yk)) return (itr.s<=x)&&(x<=itr.t);// [ , ]
if(itr.zk&&(!itr.yk)) return (itr.s<x)&&(x<=itr.t);// ( , ]
if((!itr.zk)&&itr.yk) return (itr.s<=x)&&(x<itr.t);// [ , )
}
bool cmp(range x, range y) {
if(x.s!=y.s) return x.s<y.s;
return x.t<y.t;
}
int main() {
// freopen("text.in", "r", stdin);
// freopen("text.out", "w", stdout);
scanf("%d", &t);
while(t--) {
memset(k, 0, sizeof(k));
memset(f, 0, sizeof(f));
memset(p, 0, sizeof(p));
memset(del, 0, sizeof(del));
itk = 0;
int cnt = 0, ans = 0, fp = 0; // 超速车辆个数 有用的摄像头的个数
scanf("%d %d %d %d", &n, &m, &l, &v);
for(int i=1; i<=n; i++) scanf("%d %d %d", &f[i].d, &f[i].v, &f[i].a);
for(int i=1; i<=m; i++) scanf("%d", &p[i]);
for(int i=1; i<=n; i++) {
if(f[i].a<0) {
if(f[i].v<=v) continue;
double x = f[i].d+1.0*(v*v-f[i].v*f[i].v)/(2.0*f[i].a); // 当车辆速度刚好降到限速时的位置
double xe = f[i].d-f[i].v*f[i].v*1.0/(2.0*f[i].a);
if(xe<x) {
itk++;
k[itk].s = 1.0*f[i].d, k[itk].t = xe, k[itk].zk = k[itk].yk = 0;
} else {
itk++;
k[itk].s = 1.0*f[i].d, k[itk].t = x, k[itk].zk = 0, k[itk].yk = 1;
}
} else if(f[i].a==0) {
if(f[i].v<=v) continue;
itk++;
k[itk].s = 1.0*f[i].d, k[itk].t = 1.0*l, k[itk].zk = k[itk].yk = 0; // [ , ]
} else { // a>0
double x = 1.0*f[i].d+1.0*(v*v-f[i].v*f[i].v)*1.0/(2.0*f[i].a); // 当车辆速度刚好升到限速时的位置
if(x>l) continue;
itk++;
k[itk].s = x, k[itk].t = 1.0*l, k[itk].zk = 1, k[itk].yk = 0; // ( , ]
}
}
for(int i=1; i<=itk; i++) { // 二分判断该区间内是否有摄像头拍到这辆车超速
int l = 1, r = m+1;
bool Pk = 0;
while(l<r) {
int mid = (l+r)/2;
if(check(p[mid], k[i])) {
Pk = 1;
break;
}
if(small(p[mid], k[i])) l = mid+1;
else r = mid;
}
if(Pk) cnt++;
}
printf("%d ", cnt);
sort(k+1, k+itk+1, cmp);
double minr = 0x3f3f3f3f, lst = -1;
for(int i=itk; i>=1; i--) {
if(minr<=k[i].t) del[i] = true;
minr = min(minr, k[i].t);
}
for(int i=1; i<=itk; i++) {
if(del[i]) continue;
if(k[i].s>fp) ans++, fp = k[i].t;
}
printf("%d\n", m-ans);
}
return 0;
}