搜索本质:遍历每一种情况:
此题: 对于x的每一位y都要进行遍历,使x成x*y ,x的位数最先到达n位的就是最小的操作次数; 满足宽搜的最短性,单调性,二段性;
遍历每一种情况:在遍历情况的时候,记录答案;判断答案条件;
宽搜:能不能走,走过没有,出界没有;
dist作用,初始-1,做标记走过没,而dist的值表示步数;
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>PII;
const int N=100010;
map<ll,bool>ma;
int main()
{
ll n,x;
cin>>n>>x;
queue<PII>q; //最开始设置queue<ll>q;dist[]无法记录步数;
// 因为dist数组不能开这么大;而且没有标记数组,表示搜没有搜过;
// 而此题记录每一种情况的时候,开pair,first表示当前数second记录步数;
//怎么标记走没走过呢?数组st肯定不行,数组太大;那么用map映射;
q.push({x,0});//入队,准备遍历;
ma[x]=true;//标记;
while(q.size())//当没有遍历完
{
PII k=q.front();//扩展
q.pop();//删除,不要忘记,会超时;
ll t=k.first;
ll cnt=k.second;
string s=to_string(t);//转换为字符串;
if(s.size()==n)//符合答案的条件;
{
cout<<cnt<<endl;
return 0;
}
for(int i=0;i<s.size();i++)//遍历每一位;
{
int res=s[i]-'0';
if(res>1&&ma[res*t]==false)//入队条件;
{
q.push({res*t,cnt+1});//入队
ma[t*res]=true;//标记走过;
}
}
}
cout<<-1<<endl;//没有答案输出-1;
return 0;
}
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<ll,int>PII;
const int N=200010;
int t,n,m;
int a[N];
void solve()
{
ll n,x;
cin>>n>>x;
string s=to_string(x);
int flag=0;
for(int i=0;i<s.size();i++)//特判x中有没有>1的数;因为乘1或者0的数x不会改变;
{
if(s[i]-'0'>1)flag=1;
}
if(flag==0)
{
cout<<-1<<endl;
return ;
}
queue<pair<ll,int>>q;
q.push({x,0});//前者表示x的值,后者表示次数;
map<ll,int>ma;
ma[x]=0;
while(q.size())
{
PII k=q.front();
ll t=k.first;
int cnt=k.second;
q.pop();
if(to_string(t).size()>n)continue;
if(to_string(t).size()==n)//x的位数为n,输出答案;
{
cout<<cnt<<endl;
return ;
}
set<int>s;//存当前x的每一位;
for(auto it:to_string(t))
if(it!='0')s.insert(it-'0');
for(auto i:s)//扩展队头;
{
if(!ma.count(t*i))
{
ma[t*i]=cnt+1;
q.push({t*i,cnt+1});
}
}
}
cout<<-1<<endl;//不满足的时候,不能扩展,输出-1;根前边特判一样;
}
int main()
{
t=1;
while(t--)
{
solve();
}
return 0;
}