SWERC 2022-2023 - Online Mirror H. Beppa and SwerChat (双指针)

Beppa and SwerChat

题面翻译

B和她的怪胎朋友在某个社交软件上的聊天群聊天。
这个聊天群有包括B在内的n名成员,每个成员都有自己从1-n的独特id。
最近使用这个聊天群的成员将会在列表最上方,接下来较次使用聊天软件的成员将会在列表第二名,依次类推。
B会在上午9点和晚上22点登录,并记录这时的列表。
B确保同一时间只有一个人登录,并且在九点和22点并没有其他人登录。
请你输出在9-22点之间的一种成员登录过的最小数量。

题目描述

Beppa and her circle of geek friends keep up to date on a group chat in the instant messaging app SwerChat $ ^{\text{TM}} $ .

The group has $ n $ members, excluding Beppa. Each of those members has a unique ID between $ 1 $ and $ n $ . When a user opens a group chat, SwerChat $ ^{\text{TM}} $ displays the list of other members of that group, sorted by decreasing times of last seen online (so the member who opened the chat most recently is the first of the list). However, the times of last seen are not displayed.

Today, Beppa has been busy all day: she has only opened the group chat twice, once at 9:00 and once at 22:00. Both times, she wrote down the list of members in the order they appeared at that time. Now she wonders: what is the minimum number of other members that must have been online at least once between 9:00 and 22:00?

Beppa is sure that no two members are ever online at the same time and no members are online when Beppa opens the group chat at 9:00 and 22:00.

输入格式

Each test contains multiple test cases. The first line contains an integer t t t ( 1 ≤ t ≤ 10   000 1 \leq t \leq 10\,000 1t10000 ) — the number of test cases. The descriptions of the $ t $ test cases follow.

The first line of each test case contains an integer n n n ( 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1n105 ) — the number of members of the group excluding Beppa.

The second line contains $ n $ integers $ a_1, , a_2, , \dots, , a_n $ ( $ 1 \le a_i \le n $ ) — the list of IDs of the members, sorted by decreasing times of last seen online at 9:00.

The third line contains $ n $ integers $ b_1, , b_2, , \dots, , b_n $ ( $ 1 \le b_i \le n $ ) — the list of IDs of the members, sorted by decreasing times of last seen online at 22:00.

For all $ 1\le i < j\le n $ , it is guaranteed that $ a_i \ne a_j $ and $ b_i \ne b_j $ .

It is also guaranteed that the sum of the values of $ n $ over all test cases does not exceed $ 10^5 $ .

输出格式

For each test case, print the minimum number of members that must have been online between 9:00 and 22:00.

样例 #1

样例输入 #1

4
5
1 4 2 5 3
4 5 1 2 3
6
1 2 3 4 5 6
1 2 3 4 5 6
8
8 2 4 7 1 6 5 3
5 6 1 4 8 2 7 3
1
1
1

样例输出 #1

2
0
4
0

提示

In the first test case, members 4 , 5 4, 5 4,5 must have been online between 9:00 and 22:00.

In the second test case, it is possible that nobody has been online between 9:00 and 22:00.


这题的时间复杂度允许使用双指针的方法。

看到这道题会很自然的想到两种方法,一个是根据第一次看见的信息去推,另一个是根据第二次看见的信息去倒推。
那么对于两种方法都是去比较另一个序列里存在的和自己的公共子序列的长度,然后余下的就是顺序变化的。
然而对于从前往后推,如果使用双指针的方法,那么就会导致错误,例如以下样例:

2
2 1 3
2 3 1

如果根据从前往后推的方式,是无法正常判断出到底有多少元素变动了。
所以我们采取从后往前推的方式。

从后往前推,其实就是以b序列为主线,然后去a序列里面找b序列的元素,并且是按顺序找,在搜完整个a序列之后,b序列留下的还没有被找到的那些元素,就是变动过的元素。

为什么要这样找 ?
在这里,我们必须要保证按照b序列元素的顺序找,只要模拟一下就可以明了。

对于以上给出的样例:

2
2 1 3
2 3 1

我们凭借人类的思维去判断这里有两个元素的思路就是:发现了3移动到了1的前面,又因为2在3的前面,所以2和3一定都变动了。
那么如果两个序列是这样的

1 2 3
3 1 2

我们就会说只有一个序列变化了,因为只有3变动到了1 2这个连续子串的前面。
所以就是如此的思路。 (数学的思路不会证明)


CODE:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;

int a[N];
int b[N];
int n;

void solve(){
    cin >> n;
    for(int i = 1;i <= n;i++)cin >> a[i];
    for(int i = 1;i <= n;i++)cin >> b[i];

    int pA = n,pB = n;
    while(pA >= 1 && pB >= 1){
        while(a[pA] != b[pB] && pA >= 1)pA--;
        if(pA >= 1)pB--;	//这里要不超出边界的时候才去减,不然会减多
    }
    cout << pB << endl;
}

int main(){
    int T;cin >> T;
    while(T--){
        solve();
    }
    return 0;
}
  • 12
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值