P1032 字串变换
这道题很多坑,坑了我一天
1.设置一个map,防止重复搜索
2.字符串的子串有多处相同,第五个点wa
3.自己代码写的有点乱
4.标志串不能简单直接替换,因为把y 换成yz就会死循环,要弄个别的字符来替换
5.replace的两种写法,迭代器法和下标法
总之:这题很烦
#include <bits/stdc++.h>
using namespace std;
string a[8],b[8];
struct node
{
string x;
int cnt;//cnt记录步数
};
queue<node>q;
map<string,int>ma;//防止重复搜索
int main()
{
int n=0;
int flag=0;
while(cin>>a[n]>>b[n])
{
n++;if(n>6)break;
}
q.push({a[0],0});//先把起点入队,开始时cnt=0
while(!q.empty())//开始搜索,用队列实现BFS,当队列为空还未到终点,则无法达到终点(求最短步数实际上已经保证了一定能到终点)
{
node tmp=q.front();q.pop();//按队列顺序依次取出队首tmp
if(tmp.cnt>10)break;
if(tmp.x==b[0]){printf("%d\n",tmp.cnt);flag=1;break;}//找到终点,输出答案,搜索结束
//a[tmp.x][tmp.y]='1';//原节点变为"墙"
if(ma[tmp.x])continue;
else ma[tmp.x]=1;
for(int i=1;i<n;i++)//四个方向搜索,寻找可行的下一个新节点
{
//newx=tmp.x+dir[i][0];
//newy=tmp.y+dir[i][1];
//if(newx>=1&&newx<=n&&newy>=1&&newy<=n&&a[newx][newy]=='0')
//{a[newx][newy]='1';q.push({newx,newy,tmp.cnt+1});}//新节点入队,并且走到新节点的步数是原节点的步数加一
string str1=tmp.x;
while(1)
{
int t=str1.find(a[i]);
if(t==-1)break;
string str=tmp.x;
str.replace(t,a[i].length(),b[i]);
q.push({str,tmp.cnt+1});
str1[t]='&';
}
}
}
if(flag==0)cout<<"NO ANSWER!"<<endl;
return 0;
}
nefu1519 林大超市买水果-搜索
经典搜索题型,运用到回溯
一直纳闷这题 咋标记
理解:往两种方向发展
1.不选这个
2.选这个
#include <bits/stdc++.h>
using namespace std;
int n,m,sum,newx,newy,k,fl;//必须都要定义在前面,养成习惯
int a[35];
int flag[35];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
void dfs(int sum,int cnt)
{
if(sum<0||cnt>k||fl==1)return ;
if(sum==0&&cnt==k){fl=1;return ;}
if(sum==0&&cnt!=k)return;
for(int i=1;i<=n;i++)
{
if(flag[i])continue;
flag[i]=1;
dfs(sum-a[i],cnt+1);
flag[i]=0;//回溯
}
}
int main()
{
cin>>m>>n>>k;
int ant=0;
for(int i=1;i<=n;i++){scanf("%d",&a[i]);ant+=a[i];}
if(ant<m)printf("No\n");//特解直接处理
else
{
dfs(m,0);
if(fl)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
nefu170201迷宫-搜索
记忆化搜索,把搜索结果存储起来,达到优化时间利用的结果
#include <bits/stdc++.h>
using namespace std;
char a[1001][1001];
int vis[1005][1005],flag[1005][1005];
int num[1000005];
int n,beginx,beginy,endx,endy,newx,newy,m;
int dir[8][2]={{1,0},{-1,0},{0,-1},{0,1}};//定义上下左右四个方向
struct node
{
int x,y,cnt;//cnt记录步数
};
queue<node>q;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i]+1;//以1、1为起点输入二维字符数组
int ant=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(flag[i][j]==0)
q.push({i,j,0});//先把起点入队,开始时cnt=0
int cnt=1;
while(!q.empty())//开始搜索,用队列实现BFS,当队列为空还未到终点,则无法达到终点(求最短步数实际上已经保证了一定能到终点)
{
node tmp=q.front();q.pop();//按队列顺序依次取出队首tmp
//找到终点,输出答案,搜索结束
flag[tmp.x][tmp.y]=1;//原节点变为"墙"
vis[tmp.x][tmp.y]=ant;
num[ant]=max(num[ant],cnt);
for(int i=0;i<4;i++)//四个方向搜索,寻找可行的下一个新节点
{
newx=tmp.x+dir[i][0];
newy=tmp.y+dir[i][1];
if(newx>=1&&newx<=n&&newy>=1&&newy<=n&&a[newx][newy]!=a[tmp.x][tmp.y]&&flag[newx][newy]==0)
{flag[newx][newy]=1;cnt++;q.push({newx,newy,tmp.cnt+1});vis[newx][newy]=ant;num[ant]=max(num[ant],cnt);}//新节点入队,并且走到新节点的步数是原节点的步数加一
}
}
ant++;
}
int x,y;
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",num[vis[x][y]]);
}
return 0;
}