从去年十月一参加学校集训之后才接触C,本蒟蒻最近才开始正式刷搜索题(进度感人...),刚开始写搜索板子题还挺开心的,后来接触到一些比较灵活的题就有些无从下手了,希望能通过多见识题型来填充空缺...
这道题算是一道深搜的板子题吧,就我个人理解, 深搜分为宽度(for)和深度(递归深度) ,深度通过if剪枝处理, 宽度就本蒟蒻而言可以通过标记来进行处理(本蒟蒻现在只做了10几道搜索题, 见识较浅), 当然通过做一些题,我开始觉得搜索是一种思想, 板子可能就是实现的形式, 但很多搜索题并不能套用板子, 但其中的思想是适用的。闲言少叙, 对于这道题, 可以将题拆分为深度和宽度这两部分思考,宽度就是手指所代表的数字大小, 深度就是手指个数, 大家这么思考下可能更便于对这道题的理解, 思想大概就是这样, 好, 接下放题解
#include<bits/stdc++.h>
using namespace std;
long long n, m, tool=0;
bool mark[10005];//用于标记手指是否已使用
int arr2[10005], arr[10005];
void print()//打印最终的手指顺序
{
for(long long i=0; i<n; i++)
{
printf("%d ", arr2[i]);
}
return ;
}
int num2=-1;//用于记录寻找次数
int tool2=0;//用于控制寻找初始手指顺序
void dfs(int num1)
{
if(tool==1)
return ;
if(num1==n)//找完初始手指顺序后解除, tool2标记
{
tool2++;
num2++;
}
if(num2==m&&num1==n)
{
tool=1;
print();
return ;
}
for(int i=1; i<=n ;i++)
{
if(tool2==0)//找到初始手指顺序, 并控制深度
i=arr[num1];//(这部分思想相当巧妙, 当时想到了但不会实现 。。。)
if(!mark[i])//在初始基础上进行m次搜索
{
mark[i]=1;
arr2[num1]=i;
dfs(num1+1);
mark[i]=0;
}
}
return ;
}
int main()
{
scanf("%lld %lld", &n, &m);
for(long long i=0; i<n; i++)
{
scanf("%lld", &arr[i]);//输入初始手指顺序
}
if(m==0)//如果不需要改变手指顺序
{
for(int i=0; i<n; i++)
printf("%lld ", arr[i]);
}
else
{
dfs(0);
}
return 0;
}
希望大家还有本蒟蒻能早日掌握搜索思想, 完结散花!!!