60WA on #5,6,8,10求条
查看原帖
60WA on #5,6,8,10求条
741633
Ryanhao楼主2024/11/9 15:38

rt,求超速区间推出来 s=(V+v)(Vv)2as = \dfrac{(V+v)(V-v)}{2a} 这个式子,主要是不想二分。

#include <cstdio>
#include <utility>
#include <vector>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;

pair<int,int> pt[100005],qj[100005]; 
int mac[100005];
bool flg[100005];

void mian() {
  int n,m,L,V;
  scanf("%d%d%d%d",&n,&m,&L,&V);
  for (int i = 1; i <= n; i++) {
    long double d,v,a;
    scanf("%Lf%Lf%Lf",&d,&v,&a);
    if (a <= 0 && v <= V) { pt[i] = make_pair(-1,-1); continue; } // never out of speed
    if (a >= 0 && v > V) { pt[i] = make_pair(int(d),L); continue; }
    long double s = (V+v)*(V-v)/2/a;
    //printf("car no.%d dis to V: %.5lf\n",i,s);
    if (a < 0) {
      // More & more slow, the last machine he met is floor(d+s).
      pt[i] = make_pair(int(d),min(int(d+s),L));
    } else {
      // More & more fast, the first machine he met is ceil(d+s).
      if (int(d+s+0.5) <= L) pt[i] = make_pair(int(d+s+0.5),L);
      else pt[i] = make_pair(-1,-1);
    }
  }
  //for (int i = 1; i <= n; i++) printf("%d:[%d,%d]\n",i,pt[i].first,pt[i].second);
  for (int i = 1; i <= m; i++) {
    scanf("%d",mac+i);
  }
  mac[m+1] = 0x3f3f3f3f;
  sort(mac+1,mac+m+2);
  sort(pt+1,pt+n+1,[](pair<int,int>x, pair<int,int>y) {
    if (x.first == y.first) return x.second > y.second;
    return x.first < y.first;
  });
  // Let me think what i'm doin'.
  // Y na, first i should record the be-covered part. The out-side ones are useless. We can throw'em like rubbish.
  int ans1 = 0, cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (pt[i].first == -1) continue;
    int fmc = mac[lower_bound(mac+1,mac+m+2,pt[i].first)-mac];
    if (pt[i].second < fmc) continue; // No checkers in here
    ans1++; qj[++cnt] = pt[i];
  }
  int minsec = 0x3f3f3f3f;
  for (int i = cnt; i >= 1; i--) {
    if (minsec <= qj[i].second) {
      flg[i] = 1;
    } else {
      minsec = qj[i].second;
    }
  }
  //for (int i = 1; i <= n; i++) if (!flg[i]) printf("  %d:[%d,%d]\n",i,qj[i].first,qj[i].second);
  int lst = 0, ans2 = m;
  for (int i = 1; i <= cnt; i++) {
    if (flg[i]) continue;
    if (lst < qj[i].first) {
      ans2--;
      lst = mac[upper_bound(mac+1,mac+m+2,qj[i].second)-mac-1]; // The last machine in here
    }
    //printf("last mac: %d\n",lst);
  }
  printf("%d %d\n",ans1,ans2);
  memset(flg,0,sizeof flg);
  //puts("--------------------------------");
}

int main() {
  //freopen("detect4.in","r",stdin);
  //freopen("detect.out","w",stdout);
  int T;
  scanf("%d",&T);
  while(T--) mian();
  return 0;
} 
2024/11/9 15:38
加载中...