我记得在遥远的2017年,我会敲的搜索也只有暴力枚举了。那个时候的我深搜刚会一丢丢,所以也只配切切水题,然而经常死循环RE那是肯定的。如今的我因为在多次比赛中都死于搜索,那就必须得认真磕一下了。
其实是这样的:我眼里认为的暴力就真的只是暴力,暴力无非就两种:枚举打表和模拟。然而在这么多次比赛后,我总能听到那些dalao在那边说,这道题么暴力可以拿多少多少分。我听了一脸懵逼。我怎么就一分都拿不到。这个时候我才如梦初醒,发现他们说的暴力其实都是指深搜。于是我就不得不去学深搜了。
然而,事实上,我发现深搜真的很简单。
于是,我切了好多题库第三页上的搜索题,有深搜的,也有广搜的。
我还记得那个时候稚嫩的我连那么简单的广搜都听不懂,还是涵神讲的。我竟然都听不懂。现在我发现广搜也就那样。所以我估计那时候我是因为对队列的理解不够深刻导致的。
ok,板子来几个。
T1细胞染色
直接深搜:从每一个非0的数开始搜,如果碰到与它相邻的非0的数,那就把它变成0。
#include<bits/stdc++.h>
using namespace std;
int m,n,ans;
char a[110][110];
string s;
inline int read()
{
int num=0,flag=1;
char c=getchar();
for (;c<'0'||c>'9';c=getchar())
if (c=='-') flag=-1;
for (;c>='0'&&c<='9';c=getchar())
num=(num<<3)+(num<<1)+c-48;
return num*flag;
}
void dfs(int x,int y)
{
if (a[x][y]=='0') return;
a[x][y]='0';
dfs(x-1,y);
dfs(x+1,y);
dfs(x,y-1);
dfs(x,y+1);
}
int main()
{
m=read();
n=read();
for (int i=0;i<=m+1;++i)
for (int j=0;j<=n+1;++j)
a[i][j]='0';
for (int i=1;i<=m;++i)
{
for (int j=1;j<=n;++j)
a[i][j]=getchar();
getline(cin,s);
}
for (int i=1;i<=m;++i)
for (int j=1;j<=n;++j)
if (a[i][j]!='0')
{
ans++;
dfs(i,j);
}
printf("%d\n",ans);
return 0;
}
T2迷宫
深搜+回溯:要多开一个b数组标记该点是否被访问过,如果已经访问过了再去访问就会死循环。
#include<bits/stdc++.h>
using namespace std;
int n,m,t,sx,sy,fx,fy,x,y,ans;
bool a[10][10],b[10][10];
inline int read()
{
int num=0,flag=1;
char c=getchar();
for (;c<'0'||c>'9';c=getchar())
if (c=='-') flag=-1;
for (;c>='0'&&c<='9';c=getchar())
num=(num<<3)+(num<<1)+c-48;
return num*flag;
}
void dfs(int x,int y)
{
if (x<1||x>n||y<1||y>m||a[x][y]||b[x][y]) return;
if (x==fx&&y==fy)
{
ans++;
return;
}
b[x][y]=true;
dfs(x-1,y);
dfs(x+1,y);
dfs(x,y-1);
dfs(x,y+1);
b[x][y]=false;
}
int main()
{
n=read();
m=read();
t=read();
sx=read();
sy=read();
fx=read();
fy=read();
for (int i=1;i<=t;++i)
{
x=read();
y=read();
a[x][y]=true;
}
dfs(sx,sy);
printf("%d\n",ans);
return 0;
}
T3八皇后
这道题调了好久,用了好多不同的方法来写,结果反正就是那些小问题。最近发现我调题都可以调好久,估计又fuzao了。
#include<bits/stdc++.h>
using namespace std;
int n,ans,a[100],b[100][100];
inline int read()
{
int num=0,flag=1;
char c=getchar();
for (;c<'0'||c>'9';c=getchar())
if (c=='-') flag=-1;
for (;c>='0'&&c<='9';c=getchar())
num=(num<<3)+(num<<1)+c-48;
return num*flag;
}
void dfs(int x,int y)
{
a[x]=y;
if (x==n)
{
ans++;
if (ans<=3)
{
for (int i=1;i<=n;++i)
if (i!=n) printf("%d ",a[i]);
else printf("%d",a[i]);
printf("\n");
}
return;
}
for (int i=1;i<=n;++i)
if (b[x+1][i]==0)
{
for (int j=x+2;j<=n;++j)
{
if (x+1+i-j>=1) b[j][x+1+i-j]++;
b[j][i]++;
b[j][i-x-1+j]++;
}
dfs(x+1,i);
for (int j=x+2;j<=n;++j)
{
if (x+1+i-j>=1) b[j][x+1+i-j]--;
b[j][i]--;
b[j][i-x-1+j]--;
}
}
}
int main()
{
n=read();
dfs(0,0);
printf("%d\n",ans);
return 0;
}
T4青铜莲花池
BFS八个方向。发现bfs的板子都差不多:首先,该进队的都进队。然后,取队头,向几个方向都遍历一次。如果符合要求,该点进队,ans数组更新。当然,这里也需要开一个b数组来存储当前点是否已经入过队。
#include<bits/stdc++.h>
using namespace std;
int m,n,m1,m2,a[35][35],sx,sy,fx,fy,ans[35][35];
int dx[10],dy[10];
bool b[35][35];
struct queue
{
int x,y;
}
q[1010];
inline int read()
{
int num=0,flag=1;
char c=getchar();
for (;c<'0'||c>'9';c=getchar())
if (c=='-') flag=-1;
for (;c>='0'&&c<='9';c=getchar())
num=(num<<3)+(num<<1)+c-48;
return num*flag;
}
void bfs()
{
int head=1,tail=0;
q[++tail].x=sx;
q[tail].y=sy;
b[sx][sy]=true;
while (head<=tail)
{
int kx=q[head].x,ky=q[head++].y;
for (int i=0;i<8;++i)
{
int xx=kx+dx[i],yy=ky+dy[i];
if ((a[xx][yy]==1||a[xx][yy]==4)&&!b[xx][yy])
{
q[++tail].x=xx;
q[tail].y=yy;
ans[xx][yy]=ans[kx][ky]+1;
b[xx][yy]=true;
}
}
}
}
int main()
{
m=read();
n=read();
m1=read();
m2=read();
for (int i=1;i<=m;++i)
for (int j=1;j<=n;++j)
{
a[i][j]=read();
if (a[i][j]==3)
{
sx=i;
sy=j;
}
if (a[i][j]==4)
{
fx=i;
fy=j;
}
}
dx[0]=-m1;dy[0]=-m2;
dx[1]=m1;dy[1]=-m2;
dx[2]=-m1;dy[2]=m2;
dx[3]=m1;dy[3]=m2;
dx[4]=-m2;dy[4]=-m1;
dx[5]=m2;dy[5]=-m1;
dx[6]=-m2;dy[6]=m1;
dx[7]=m2;dy[7]=m1;
bfs();
printf("%d\n",ans[fx][fy]);
return 0;
}
T5爱心企鹅
7.19牛客②I
广搜板子↓
#include<bits/stdc++.h>
using namespace std;
int dx1[4]={1,0,0,-1},dy1[4]={0,-1,1,0};
int dx2[4]={1,0,0,-1},dy2[4]={0,1,-1,0};
char s[4]={'D','L','R','U'};
char a[50][50],b[50][50],u,v,x,y,ans[410];
int c[50][50][50][50],t;
struct acm
{
int u,v,x,y;
char d;
}
f[50][50][50][50];
queue<acm> q;
inline int read()
{
int num=0,flag=1;
char c=getchar();
for (;c<'0'||c>'9';c=getchar())
if (c=='-') flag=-1;
for (;c>='0'&&c<='9';c=getchar())
num=(num<<3)+(num<<1)+c-48;
return num*flag;
}
void bfs()
{
acm st{20,20,20,1};
q.push(st);
while (q.size())
{
acm now=q.front();
q.pop();
for (int k=0;k<4;++k)
{
acm nxt{now.u+dx1[k],now.v+dy1[k],now.x+dx2[k],now.y+dy2[k]};
if (nxt.u<1||nxt.v<1||nxt.u>20||nxt.v>20||a[nxt.u][nxt.v]=='#')
{
nxt.u=now.u;
nxt.v=now.v;
}
if (nxt.x<1||nxt.y<1||nxt.x>20||nxt.y>20||b[nxt.x][nxt.y]=='#')
{
nxt.x=now.x;
nxt.y=now.y;
}
if (!c[nxt.u][nxt.v][nxt.x][nxt.y]&&(nxt.u!=20||nxt.v!=20||nxt.x!=20||nxt.y!=1))
{
q.push(nxt);
c[nxt.u][nxt.v][nxt.x][nxt.y]=c[now.u][now.v][now.x][now.y]+1;
f[nxt.u][nxt.v][nxt.x][nxt.y].u=now.u;
f[nxt.u][nxt.v][nxt.x][nxt.y].v=now.v;
f[nxt.u][nxt.v][nxt.x][nxt.y].x=now.x;
f[nxt.u][nxt.v][nxt.x][nxt.y].y=now.y;
f[nxt.u][nxt.v][nxt.x][nxt.y].d=s[k];
}
if (nxt.u==1&&nxt.v==20&&nxt.x==1&&nxt.y==1)
{
printf("%d\n",c[nxt.u][nxt.v][nxt.x][nxt.y]);
a[nxt.u][nxt.v]='A';
b[nxt.x][nxt.y]='A';
while (nxt.u!=20||nxt.v!=20||nxt.x!=20||nxt.y!=1)
{
ans[++t]=f[nxt.u][nxt.v][nxt.x][nxt.y].d;
u=f[nxt.u][nxt.v][nxt.x][nxt.y].u;
v=f[nxt.u][nxt.v][nxt.x][nxt.y].v;
x=f[nxt.u][nxt.v][nxt.x][nxt.y].x;
y=f[nxt.u][nxt.v][nxt.x][nxt.y].y;
nxt.u=u;
nxt.v=v;
nxt.x=x;
nxt.y=y;
a[nxt.u][nxt.v]='A';
b[nxt.x][nxt.y]='A';
}
for (int i=t;i>=1;--i)
putchar(ans[i]);
printf("\n");
for (int i=1;i<=20;++i)
{
for (int j=1;j<=20;++j)
putchar(a[i][j]);
printf(" ");
for (int j=1;j<=20;++j)
putchar(b[i][j]);
printf("\n");
}
exit(0);
}
}
}
}
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
for (int i=1;i<=20;++i)
{
for (int j=1;j<=20;++j)
{
a[i][j]=getchar();
while (a[i][j]!='.'&&a[i][j]!='#')
a[i][j]=getchar();
}
for (int j=1;j<=20;++j)
{
b[i][j]=getchar();
while (b[i][j]!='.'&&b[i][j]!='#')
b[i][j]=getchar();
}
}
bfs();
fclose(stdin);
fclose(stdout);
return 0;
}
T6水管
7.17牛客①E
广搜加强↓
#include<bits/stdc++.h>
using namespace std;
int T,n,m,a[1005][1005],x,y,id,d,t;
bool b[1005][1005][6][4];
map<char,int> s;
struct acm
{
int x,y,id,d;
}
f[1005][1005][6][4],c[20000010];
queue<acm> q;
inline int read()
{
int num=0,flag=1;
char c=getchar();
for (;c<'0'||c>'9';c=getchar())
if (c=='-') flag=-1;
for (;c>='0'&&c<='9';c=getchar())
num=(num<<3)+(num<<1)+c-48;
return num*flag;
}
void add(acm nxt,acm now)
{
q.push(nxt);
b[nxt.x][nxt.y][nxt.id][nxt.d]=true;
f[nxt.x][nxt.y][nxt.id][nxt.d].x=now.x;
f[nxt.x][nxt.y][nxt.id][nxt.d].y=now.y;
f[nxt.x][nxt.y][nxt.id][nxt.d].id=now.id;
f[nxt.x][nxt.y][nxt.id][nxt.d].d=now.d;
}
void bfs()
{
while (q.size())
q.pop();
if (a[1][1]<=3)
{
acm st{1,1,1,s['R']};
q.push(st);
b[st.x][st.y][st.id][st.d]=true;
}
else
{
acm st{1,1,5,s['D']};
q.push(st);
b[st.x][st.y][st.id][st.d]=true;
}
while (q.size())
{
acm now=q.front();
q.pop();
if (now.d==s['U'])
{
if (a[now.x-1][now.y]<=3)
{
acm nxt1{now.x-1,now.y,2,s['R']};
acm nxt2{now.x-1,now.y,3,s['L']};
if (~a[nxt1.x][nxt1.y+1]&&!b[nxt1.x][nxt1.y][nxt1.id][nxt1.d]) add(nxt1,now);
if (~a[nxt2.x][nxt2.y-1]&&!b[nxt2.x][nxt2.y][nxt2.id][nxt2.d]) add(nxt2,now);
}
else
{
acm nxt{now.x-1,now.y,5,s['U']};
if (~a[nxt.x-1][nxt.y]&&!b[nxt.x][nxt.y][nxt.id][nxt.d]) add(nxt,now);
}
}
if (now.d==s['L'])
{
if (a[now.x][now.y-1]<=3)
{
acm nxt1{now.x,now.y-1,1,s['U']};
acm nxt2{now.x,now.y-1,2,s['D']};
if (~a[nxt1.x-1][nxt1.y]&&!b[nxt1.x][nxt1.y][nxt1.id][nxt1.d]) add(nxt1,now);
if (~a[nxt2.x+1][nxt2.y]&&!b[nxt2.x][nxt2.y][nxt2.id][nxt2.d]) add(nxt2,now);
}
else
{
acm nxt{now.x,now.y-1,4,s['L']};
if (~a[nxt.x][nxt.y-1]&&!b[nxt.x][nxt.y][nxt.id][nxt.d]) add(nxt,now);
}
}
if (now.d==s['R'])
{
if (a[now.x][now.y+1]<=3)
{
acm nxt1{now.x,now.y+1,0,s['U']};
acm nxt2{now.x,now.y+1,3,s['D']};
if (~a[nxt1.x-1][nxt1.y]&&!b[nxt1.x][nxt1.y][nxt1.id][nxt1.d]) add(nxt1,now);
if (~a[nxt2.x+1][nxt2.y]&&!b[nxt2.x][nxt2.y][nxt2.id][nxt2.d]) add(nxt2,now);
}
else
{
acm nxt{now.x,now.y+1,4,s['R']};
if (~a[nxt.x][nxt.y+1]&&!b[nxt.x][nxt.y][nxt.id][nxt.d]) add(nxt,now);
}
}
if (now.d==s['D'])
{
if (a[now.x+1][now.y]==6)
{
t=0;
while (now.x)
{
c[++t].x=now.x;
c[t].y=now.y;
c[t].id=now.id;
x=f[now.x][now.y][now.id][now.d].x;
y=f[now.x][now.y][now.id][now.d].y;
id=f[now.x][now.y][now.id][now.d].id;
d=f[now.x][now.y][now.id][now.d].d;
now.x=x;
now.y=y;
now.id=id;
now.d=d;
}
printf("YES\n");
printf("%d\n",2*t);
for (int i=t;i>=1;--i)
{
if (c[i].id==a[c[i].x][c[i].y]) printf("1 0 %d %d\n",c[i].x,c[i].y);
else if (c[i].id-a[c[i].x][c[i].y]==1||c[i].id==0&&a[c[i].x][c[i].y]==3)
{
printf("1 90 %d %d\n",c[i].x,c[i].y);
a[c[i].x][c[i].y]=c[i].id;
}
else if (c[i].id-a[c[i].x][c[i].y]==2||a[c[i].x][c[i].y]-c[i].id==2)
{
printf("1 180 %d %d\n",c[i].x,c[i].y);
a[c[i].x][c[i].y]=c[i].id;
}
else
{
printf("1 270 %d %d\n",c[i].x,c[i].y);
a[c[i].x][c[i].y]=c[i].id;
}
printf("0 %d %d\n",c[i].x,c[i].y);
}
return;
}
if (a[now.x+1][now.y]<=3)
{
acm nxt1{now.x+1,now.y,0,s['L']};
acm nxt2{now.x+1,now.y,1,s['R']};
if (~a[nxt1.x][nxt1.y-1]&&!b[nxt1.x][nxt1.y][nxt1.id][nxt1.d]) add(nxt1,now);
if (~a[nxt2.x][nxt2.y+1]&&!b[nxt2.x][nxt2.y][nxt2.id][nxt2.d]) add(nxt2,now);
}
else
{
acm nxt{now.x+1,now.y,5,s['D']};
if (~a[nxt.x+1][nxt.y]&&!b[nxt.x][nxt.y][nxt.id][nxt.d]) add(nxt,now);
}
}
}
printf("NO\n");
}
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
s['U']=0;
s['L']=1;
s['R']=2;
s['D']=3;
T=read();
while (T--)
{
n=read();
m=read();
for (int j=0;j<=m+1;++j)
a[0][j]=-1;
for (int i=0;i<=n+1;++i)
a[i][0]=-1;
for (int i=0;i<=n+1;++i)
a[i][m+1]=-1;
for (int j=0;j<=m+1;++j)
a[n+1][j]=-1;
a[n+1][m]=6;
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
{
a[i][j]=read();
for (int k=0;k<6;++k)
for (int l=0;l<4;++l)
b[i][j][k][l]=false;
}
bfs();
}
fclose(stdin);
fclose(stdout);
return 0;
}