zoukankan      html  css  js  c++  java
  • 【Cf #503 B】The hat(二分)

    为什么Cf上所有的交互题都是$binary ; Search$。。。

    把序列分成前后两个相等的部分,每一个都可以看成一条斜率为正负$1$的折线。我们把他们放在一起,显然,当折线的交点的横坐标为整数时有解。

    我们考虑序列元素$a_{i}, a_{i + frac{n}{2}}$,他们的差的奇偶性对于每一个$i$都是一样的,因为随着横坐标的增加,纵坐标之差要么不变,要么加减$2$。

    显然如果我们询问$a_{1}, a_{1 + frac{n}{2}}$的差是奇数,那就不可能存在解了。

    我们把折线的左右边界设成重合,也就是第一条折线的右边界的点就是第二条折线左边界的点。不考虑边界处相交时,显然两条折线是交错的,于是必定有交点。

    我们只要求出任意一组解就可以了,于是可以二分,可以快速判断左右区间中哪一个一定存在解,根据交错必定有解就可以了。

    $igodot$技巧&套路:

    • 根据奇偶性可以证明将问题简化
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    const int N = 100005;
    
    int n, a[N];
    
    int Ask(int p) {
      cout << "? " << p << endl;
      cin >> a[p];
      cout << "? " << p + n / 2 << endl;
      cin >> a[p + n / 2];
      if (a[p] == a[p + n / 2]) {
        cout << "! " << p << endl;
        exit(0);
      }
      return a[p] < a[p + n / 2];
    }
    
    int main() {
      scanf("%d", &n);
      int type = Ask(1);
      if ((a[1] - a[1 + n / 2]) & 1) {
        cout << "! -1" << endl;
        return 0;
      }
      int nl = 2, nr = n / 2;
      for (int md; nl <= nr; ) {
        md = (nl + nr) >> 1;
        if (Ask(md) == type) {
          nl = md + 1;
        } else {
          nr = md - 1;
        }
      }
      
      return 0;
    }
    View Code
  • 相关阅读:
    今日计划
    今日计划
    个人品质
    翻译 《Why Indy?》计划&进度表
    今日计划
    一粒老鼠屎
    开两本字典聊天的感觉
    ObjectiveC初学指南
    todo格式定义
    制作TortoiseSVN最新版本的中文DLL(转)
  • 原文地址:https://www.cnblogs.com/Dance-Of-Faith/p/9469696.html
Copyright © 2011-2022 走看看