科大讯飞笔试
第三题
自然语言处理( nlp)经常会需要解决一些字符串的子串问题。我们把它抽象为数组的连续了数组问题。当处理一个数组时,机器会存储数组的一些连续了数组。不过为了节省存储空间,当机器遇到多个完全相同的连续子数组时只会存储一次。
现在有一个棘手的问题,给定了两个长度为n的数组,这两个数组均满足以下性质: 1 到n恰好出现了一次,请你判断机器存储完所有的连续了数组时,一共存储了多少次。
输入描述
第一行输入一个正整数n,代表数组的长度
第二行输入n个正整数a_i,代表第一个数组
第三行输入n个正整数b_i;,代表第二个数组
1小于等于n小于等于2x10^5
输出描述
机器存储的次数。
例1
输入
3
1 2 3
2 3 1
输出
8
说明
[1],[2],[3],[1,2],[2,3],[3,1],[1,2,3],[2,3,1] 共存储了8次。
这题类似于leetcode90题,回溯算法找子集问题
不同点在于,这里是两个数组,
所以这一题可以用两次回溯分别找出两个数组的子集,然后将两个自己放到set中,返回set的长度。
#include <iostream>
#include <vector>
#include <set>
using namespace std;
void backtrack(vector<int>& nums, int start, int end, set<vector<int>>& subsets) {
if (start > end) {
return;
}
vector<int> subset;
for (int i = start; i <= end; ++i) {
subset.push_back(nums[i]);
subsets.insert(subset);
backtrack(nums, i + 1, end, subsets);
}
}
int main() {
int n;
cin >> n;
vector<int> a(n);
vector<int> b(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
for (int i = 0; i < n; ++i) {
cin >> b[i];
}
set<vector<int>> subsets;
backtrack(a, 0, n - 1, subsets);
backtrack(b, 0, n - 1, subsets);
cout << subsets.size() << endl;
return 0;
}