思路分析:
这道题主要考察的是搜索、剪枝、map和vector的应用。首先我们要定义一个map,是从int型到vector型的映射,这里的vector就是一个存放int类型数据的容器,因为题目说到同样的数据会有不同的下标,如果我们按照正常的做法,要找与当前数据相同的其他位置,我们要进行循环,会超时,可如果用vector的话,只需要判断容器里面的数据如果超过一个的话,就直接在容器中找到相同数据的其他几个位置了。注意循环vector中的数据时,需要定义一个vector的迭代器。
这道题大体采用的是dfs深搜+剪枝,也就是说当你还没到终点,但是你当前的步数就已经大于等于最小步数了,就没有必要继续走下去了,就直接返回退出即可。
代码实现:
#include<bits/stdc++.h>
using namespace std;
map<int,vector<int>> mp;
int n,min1=99999;
int book[100010];
int nums[100010];
void dfs(int present,int step)
{
if(present==n)
{
if(step<min1)
min1=step;
return;
}
if(step>=min1)//判断是否需要剪枝
return;
else{
if(present<n&&book[present+1]==0)
{
book[present+1]=1;
dfs(present+1,step+1);
book[present+1]=0;
}
if(present>1&&book[present-1]==0)
{
book[present-1]=1;
dfs(present-1,step+1);
book[present-1]=0;
}
if(mp[nums[present]].size()>1)//判断vector容器大小是否大于1
{
for(vector<int>::iterator i=mp[nums[present]].begin();i!=mp[nums[present]].end();i++)
{
if(book[*i]==0)
{
book[*i]=1;
dfs(*i,step+1);
book[*i]=0;
}
}
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>nums[i];
mp[nums[i]].push_back(i);//将相同值的不同下标存到vector容器当中
}
book[1]=1;
dfs(1,0);
cout<<min1;
return 0;
}