Loading

luogu P7004 [NEERC2013]Interactive Interception 题解

题目链接

感觉比较玄学的交互,看了题解才会做。

主体的思想是,我们在二分位置的同时也对 \(v\) 的范围进行修改。

假设我们现在的区间是 \([L,R]\) ,那么我们取 \(mid=\frac{L+R}{2}\) ,然后再询问 \(check(L, mid)\)
这样可以先得到当前时间上点 \(P\) 所在位置的范围,并把范围记录下来。

接着我们枚举每一个之前我们记录下来的位置范围 \(l_i\)\(r_i\)
然后结合当前的 \(L\)\(R\) 计算题目中速度的范围,再模拟让点再向前走一步即可。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cctype>
#include <string>

#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)

using std::pair;
using std::make_pair;
using std::string;

#define pii pair<int, int>
#define mp make_pair

using ll = long long;
const int inf = 1e9;
const ll infll = 0ll + 1e18;

#define int long long
const int N = 505;

int pos, v, mxv, l[N], r[N], tot, vleft, vright;

inline int check(int l, int r) {
  std::cout << "check " << l << " " << r << std::endl;
  string res; std::cin >> res;
  if (res[0] == 'Y') return 1;
  else return 0;
}

signed main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(NULL), std::cout.tie(NULL);
  std::cin >> pos >> vright;
  int left = 0, right = pos;
  while (left < right) {
    int mid = (left + right) / 2;
    if (check(left, mid) == 1) right = mid;
    else left = mid + 1;
    for (int i = 1; i <= tot; i ++) {
      vleft = std::max(vleft, (left - r[i]) / (tot + 1 - i));
      vright = std::min(vright, (right - l[i]) / (tot + 1 - i));
    }
    tot ++;
    l[tot] = left, r[tot] = right;
    left += vleft;
    right += vright;
  }
  std::cout << "answer " << left << std::endl;
  return 0;
}
posted @ 2022-10-02 17:26  Aonynation  阅读(37)  评论(0编辑  收藏  举报