Codeforces Round 935-E Binary Search

本文讲述了作者在Codeforces比赛中解决一个问题的过程,涉及对二分查找的理解,如何通过操作控制数组使得目标数可被快速找到,以及对最终解决方案的证明。
摘要由CSDN通过智能技术生成

题目链接Problem - E - Codeforces

思路:

        开篇先说点题外话,这题当时做的时候很抽象,我是先ac之后,再证明这个思路是正确的(怕被队友hack),非常抽象。

        这个题主要考察了对二分查找的理解,给你一串没排序的数,让你在两次操作内使这个数能被查找到。一上来肯定会想到通过操作查找到的数来控制mid指向的位置,但是这种写法太麻烦了当时写了一会发现不太好写,光是找交换两个什么数的策略就很麻烦。然后又突然想到,直接移动到最中间不就行了(把题意理解错了),然后wa了一发,第一个样例都没过,然后精读了一遍题目之后,发现这个路子好像走的通,直接按照题目中给出的二分写法实现一遍找到最后L指向的位置,然后把要找的数交换过去就可以了,直接交一发就a了。

        但是Ac了之后想到是先操作再二分,这样会不会对二分过程产生什么影响?于是开始证明,下面给出证明:

假如要找的数x位于正中间,那么L稍后就会移动到x所在的位置,然后再进行查找的过程,如果遇到比x大的移动的是R,并不影响L,如果比x小,L就会移动到这个数所在的位置,因此可以得出,L最后指向的位置的数必定小于等于x,如果等于x,那么没有交换必要,小于x,交换两个值也不会对操作有什么影响。

理论通过,实践开始.(求求大佬们发现错误别hack我,呜呜呜)。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define all(a) a.begin(), a.end()
#define pb push_back
#define pii pair<int, int>
#define endl '\n'
void solve()
{
    int i, j;
    vector<int> a;//存数组
    int n, x;
    cin >> n >> x;
    int pos = 0;
    a.pb(-1);
    for (i = 1; i <= n; i++)
    {
        int tx;
        cin >> tx;
        if (tx == x)记录下来要找的数的位置
        {
            pos = i;
        }
        a.pb(tx);
    }
    int l = 1, r = n + 1, mid;//按照题目中给出的写法二分
    while (r != l + 1)    //找到最终位置
    {
        mid = l + r >> 1;
        if (a[mid] <= x)
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    if (l == pos)//相等就不移动
    {
        cout << "0" << endl;
    }
    else//不相等就移动一次
    {
        cout << "1" << endl;
        cout << l << " " << pos << endl;
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值