-
深度优先搜索
对于一种情况,直接搜索到边界再进行回溯(有爆栈风险) -
广度优先搜索
往往需要用到队列,一层一层地向下搜索 -
迭代加深搜索
兼有深搜与广搜地思路,设置深度上限,依次进行深度优先搜索,当搜索了该深度上限下所有情况时,加深深度继续进行搜索 -
记忆化搜索
搜索时记录已搜索过的情况结果,省去下一次搜索的时间,思路上与动态规划有一定相似之处 -
双向搜索
状态保存
①直接数组保存
②二进制、三进制保存法
③其他
在竞赛中,搜索题的难度往往更体现于编写,查错和剪枝上,处理不当可能会耗费相当长的时间
例题
POJ - 2531 (二进制状态保存)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int num[30][30];
int count[21]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576};
int n;
void init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&num[i][j]);
}
int main()
{
init();
int ans=-1;
bool flag[21];
int cnt[21],len;
for(int x=1;x<count[n]/2;x++)
{
memset(flag,false,sizeof(flag));
int tmp=x,id=1;len=0;
while(tmp)
{
if(tmp&1){flag[id]=true;cnt[len++]=id;}
tmp>>=1;
id++;
}
int res=0;
for(int i=0;i<len;i++)
{
for(int j=1;j<=n;j++)
if(!flag[j])res+=num[cnt[i]][j];
}
//cout<<x<<' '<<res<<endl;
if(res>ans)ans=res;
}
printf("%d\n",ans);
return 0;
}
Gym - 102056I
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
bool used[110][110];
int a,b,c;
typedef struct node
{
int l,r;
int res[50000];
int len;
}N;
queue<N>num;
void print(N ans)
{
cout<<ans.len<<endl;
for(int i=0;i<ans.len;i++)
{
switch(ans.res[i])
{
case 1: printf("FILL(1)\n");break;
case 2: printf("FILL(2)\n");break;
case 3: printf("DROP(1)\n");break;
case 4: printf("DROP(2)\n");break;
case 5: printf("POUR(1,2)\n");break;
case 6: printf("POUR(2,1)\n");break;
}
}
}
int main()
{
scanf("%d%d%d",&a,&b,&c);
for(int i=0;i<=a;i++)
for(int j=0;j<=b;j++)
used[i][j]=false;
N t;
t.l=0;t.r=0;t.len=0;num.push(t);
used[0][0]=true;
while(!num.empty())
{
N now=num.front();
num.pop();
if(now.l==c||now.r==c)
{
print(now);
return 0;
}
if(now.l!=a&&!used[a][now.r])
{
N next;
next.l=a;
next.r=now.r;
next.len=now.len+1;
for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
next.res[next.len-1]=1;
used[a][now.r]=true;
num.push(next);
}
if(now.r!=b&&!used[now.l][b])
{
N next;
next.l=now.l;
next.r=b;
next.len=now.len+1;
for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
next.res[next.len-1]=2;
used[now.l][b]=true;
num.push(next);
}
if(now.l!=0&&!used[0][now.r])
{
N next;
next.l=0;
next.r=now.r;
next.len=now.len+1;
for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
next.res[next.len-1]=3;
used[0][now.r]=true;
num.push(next);
}
if(now.r!=0&&!used[now.l][0])
{
N next;
next.l=now.l;
next.r=0;
next.len=now.len+1;
for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
next.res[next.len-1]=4;
used[now.l][0]=true;
num.push(next);
}
if(now.l!=0&&now.r!=b)
{
int l,r;
if(now.l>=b-now.r)
{
r=b;
l=now.l-b+now.r;
}
else
{
l=0;
r=now.r+now.l;
}
if(!used[l][r])
{
N next;
next.l=l;
next.r=r;
next.len=now.len+1;
for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
next.res[next.len-1]=5;
used[l][r]=true;
num.push(next);
}
}
if(now.l!=a&&now.r!=0)
{
//cout<<now.l<<' '<<now.r<<endl;
int l,r;
if(now.r>=a-now.l)
{
l=a;
r=now.r-a+now.l;
//cout<<l<<' '<<r<<endl;
}
else
{
r=0;
l=now.l+now.r;
//cout<<l<<' '<<r<<endl;
}
if(!used[l][r])
{
//cout<<l<<' '<<r<<endl;
N next;
next.l=l;
next.r=r;
next.len=now.len+1;
for(int i=0;i<now.len;i++)next.res[i]=now.res[i];
next.res[next.len-1]=6;
used[l][r]=true;
num.push(next);
}
}
}
printf("impossible\n");
return 0;
}