CodeForces - 1066C Books Queries

题意想了一会感觉也蛮好懂的,但是做的时候确实绞尽脑汁喽

一开始做的时候确实不知道往哪想,只是想着要开俩数组什么的,左一个啊,右一个…
就在这个方向上转了老长时间。
然后想到了用类,把一本书左右有多少本书属性封装起来…但是在输入一个书的信息后就不会再更新了,所以这种想法很扯。
CodeForces - 1066C Books Queries
啊,跑题了,总而言之还是在左右的基础上,慢慢联想到数轴,然后问题得以解决。

首先题目有一句话是第一本书放在哪个位置都不影响,确实不影响。
把第一本书看作原点也问心无愧了。
然后就利用数组的特性了。
以第一本书为原点(中间值),数组的负代表该书的左面空间,数组的正代表该书的右面空间

我们建立一个数组pos[maxn],pos[ i ]代表位置,下标 i 代表该书的id
所以对于第一本书的输入
pos[ id ] = 0;
其次,再设变量 a , b为数轴左右的端值,a代表左(负),b代表右(正),
如果输入是 ’ L’ ,a–,若是‘ R ’,b++。

然后对于这样的一个序列
2 6 7 8 9 1
-4 -3 -2 -1 0 1

第一行表示id,第二行表示位置。其中a = -4,b = 1;
如果寻找 id 为8的书(位置为-1)
从左数是 pos - a = 3,从右数是b - pos = 2。这样就能很简单的判断左右从哪里找更合适!!!
两个都列举出来比较取最小值即可

想的时间还是太长了…不过想出来还是蛮开心的!还要继续努力呀,呜呜呜呜!!!
CodeForces - 1066C Books Queries
下面是代码

#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 200020
int a, b;
int pos[maxn], ans[maxn];
int main()
{
    int n, id;
    char ch;
    cin >> n;
    int cnt = 0;
    for(int i = 0; i < n; ++i)
    {
        cin >> ch >> id;
        if(!i)
        {
            pos[id] = 0;
            continue;
        }
        if(ch == 'L')
        {
            a--;
            pos[id] = a;
        }
        if(ch == 'R')
        {
            b++;
            pos[id] = b;
        }
        if(ch == '?')
            ans[cnt++] = min(b-pos[id],pos[id]-a);
    }
    for(int i = 0; i < cnt; ++i)
        cout << ans[i] << endl;
    return 0;
}