不知道这个算不算剪枝,小白一个......
题目描述:
给出一个长度为n的数列A𝑖,问是否能将这个数列分解为两个长度
为n/2的子序列,满足
∙ 两个子序列不互相重叠。
∙ 两个子序列中的数要完全一样,{1, 2} = {1, 2},{1, 2} ≠ {2, 1}。
输入描述:
第一行,一个正整数T,表示数据组数。
接下来T组数据,每组数据的第一行,一个正整数n,第二行𝑛个正整数A𝑖。
输出描述:
每组数据输出一行,如果可以完成,输出Frederica Bernkastel,否则输出Furude Rika。
示例1
输入
复制
3
4
1 1 2 2
6
1 2 3 4 5 6
4
1 2 2 1
输出
复制
Frederica Bernkastel
Furude Rika
Furude Rika
解题思路:
1.考虑数据的大小,直接搜索必然超时,所以考虑用空间节约时间的方法。创建2个数组用来保存数字,进行匹配。
2.考虑用三指针的思想来处理数据,aIndex,bIndex,arrIndex,分别对应三个数组的索引(三个指针).
3.搜索方法是首先将arr第一个数字默认放进a数组里,遍历原数组arr,同时进行判定,是否是b数组索引对应的a数组的数字(这里可能有点绕,其实就是相匹配的数字)。
4.搜索面对的是两种情况:
相匹配的情况下,就可以尝试(用if去尝试 )去放进b数组之中,如果不行,就放进a数组之中;
不匹配的话直接放进a数组之中。
5.终止条件首先判断是否超出一半,其次是未超出一半的同时,arr数组遍历完毕(代表互相匹配成功)
int arr[50],a[50],b[50];
int aIndex, bIndex, arrIndex;//三个数组索引 a 和 b 的索引也代表他们的数字个数
#include<iostream>
int n;
using namespace std;
// 其实就两种情况 判断arr里面的这个数字 是否对应 不对应 直接丢a里 对应就去尝试丢b里面的情况 直到最后 来判断结果
int dfs(int aIndex, int bIndex, int arrIndex)
{
if (aIndex > n / 2 || bIndex > n / 2)
{
return 0;
}
//数组都没用掉一半
if (arrIndex > n)
{
return 1;
}
if (arr[arrIndex] == a[bIndex+1])
{
b[bIndex + 1] = arr[arrIndex];
if (dfs(aIndex, bIndex + 1, arrIndex+1))
{
return 1;
}
//回溯消除选择选择状态
b[bIndex + 1] = 0;//清除掉 可以省略 主要是思想的体现
}
a[aIndex + 1] = arr[arrIndex];
return dfs(aIndex + 1, bIndex, arrIndex + 1);
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
cin >> t;
while (t--)
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> arr[i];
}
a[1] = arr[1];//先把一个丢进去
if (dfs(1, 0, 2))
{
cout << "Frederica Bernkastel\n";
}
else
{
cout << "Furude Rika\n";
}
}
}

京公网安备 11010502036488号