第7周总结

本周看了大约52篇博客并做了10道搜索题目。

 树与搜索的组合:

zzulioj-1907-小火山的宝藏收益【DFS】_Somethingwll的博客-CSDN博客

每个节点能取的的宝藏为当前节点的宝藏或者子节点所有的宝藏和。可以使用邻接表来记下所有的数据并搜索每个节点的最大宝藏收益。

#include<bits/stdc++.h>
using namespace std;
int a,sta,a1,b1,vis[10001];
vector<int>aaa[10001];
int dfs(int x,int y)
{int max1=0;
for(int i2=0;i2<aaa[x].size();i2++)
    {if(aaa[x][i2]==y)continue;
    max1+=dfs(aaa[x][i2],x) ;}
max1=max(vis[x],max1);
return max1;
}
int main()
{std::ios::sync_with_stdio(false);
int t;cin>>t;
while(t--)
{cin>>a>>sta;
for(int i=1;i<=a;i++)
    cin>>vis[i];
    for(int i1=0;i1<a-1;i1++){
cin>>a1>>b1;
aaa[a1].push_back(b1);
aaa[b1].push_back(a1);}

cout<<dfs(sta,0)<<endl;
}

}

 下面这个题目的"包围"方法:

zzulioj-1908-小火山的围棋梦想【DFS】_Somethingwll的博客-CSDN博客

通过从上到下、从下到上、从左到右、从右到左搜索围棋外的区域并标记,最后输出时没被标记的'.'就输出'*'。

#include<bits/stdc++.h>
using namespace std;
int m,n;char aa[26][26];
bool bb[26][26];
int xx[4]={0,1,0,-1};
int yy[4]={1,0,-1,0};
void dfs(int x,int y)
{bb[x][y]=1;
for(int i=0;i<4;i++){
int dx=x+xx[i];
int dy=y+yy[i];
if(aa[dx][dy]=='.'&&!bb[dx][dy]&&dx>0&&dy>0&&dx<=m&&dy<=n)
    dfs(dx,dy);
}
}
int main()
{std::ios::sync_with_stdio(false);
int t;cin>>t;
while(t--)
{memset(bb,0,sizeof(bb));
memset(aa,'0',sizeof(aa));
cin>>m>>n;
for(int i=1;i<=m;i++)
    for(int i1=1;i1<=n;i1++)
     cin>>aa[i][i1];
 for(int i=1;i<=m;i++){
     if(aa[i][1]=='.'&&!bb[i][1])dfs(i,1);
     if(aa[i][n]=='.'&&!bb[i][n])dfs(i,n);}
 for(int i1=1;i1<=n;i1++){
      if(aa[1][i1]=='.'&&!bb[1][i1])dfs(1,i1);
      if(aa[m][i1]=='.'&&!bb[m][i1])dfs(m,i1);}
for(int i=1;i<=m;i++){
    for(int i1=1;i1<=n;i1++){
        if(aa[i][i1]=='.'&&!bb[i][i1])cout<<"* ";
    else cout<<aa[i][i1]<<" ";
    }cout<<endl;}
}
}

三维搜索: 

3​​​​​​​2251 -- Dungeon Master (poj.org)

与二维平面相比多了两个方向。

#include<bits/stdc++.h>
using namespace std;
char a[31][31][31];
int sta[3],en[3];
int xx[6]={0,1,0,-1,0,0};
int yy[6]={1,0,-1,0,0,0};
int zz[6]={0,0,0,0,1,-1};
bool v[31][31][31];
struct node{int sum,a1,a2,a3;}q1;
queue<node>q;
int main()
{std::ios::sync_with_stdio(false);
int l,r,c;
cin>>l>>r>>c;
for(int i=1;i<=l;i++)
    for(int i1=1;i1<=r;i1++)
     for(int i2=1;i2<=c;i2++)
     {cin>>a[i][i1][i2];
     if(a[i][i1][i2]=='S')
        {sta[0]=i;sta[1]=i1;sta[2]=i2;}
     if(a[i][i1][i2]=='E')
     {en[0]=i;en[1]=i1;en[2]=i2;a[i][i1][i2]='.';}
     }
q.push((struct node){0,sta[0],sta[1],sta[2]});
while(!q.empty())
{q1=q.front();
q.pop();
v[q1.a1][q1.a2][q1.a3]=1;
if(q1.a1==en[0]&&q1.a2==en[1]&&q1.a3==en[2])
    {cout<<q1.sum<<endl;return 0;}
for(int i=0;i<6;i++)
{int dx=q1.a2+xx[i];
   int dy=q1.a3+yy[i];
   int dz=q1.a1+zz[i];
   if(dx>0&&dy>0&&dz>0&&dx<=r&&dz<=l&&dy<=c&&a[dz][dx][dy]=='.'&&!v[dz][dx][dy])
   {q.push((struct node){q1.sum+1,dz,dx,dy});}
}
}
cout<<"Trapped!"<<endl;
}

 

 

3009 -- Curling 2.0 (poj.org)

这个题与平时的搜索题不太一样,之前碰到的都是走一步是一个格,搜索一次,这个题是走一条直线再搜索一次,走一条直线算一步,碰到石头停止,且该石头消失。该题目还限定了十步之内到达的条件。

#include<bits/stdc++.h>
using namespace std;
int aaa[31][31];
int xx[4]={0,1,0,-1};
int yy[4]={1,0,-1,0};

int r,c,ex,ey,ans,sx,sy;
void dfs(int x,int y,int s)
{
    if(s>10)return;
    for(int i1=0;i1<4;i1++){
    int dx=x+xx[i1];
    int dy=y+yy[i1];
    if(!aaa[dx][dy])
    {if(xx[i1]==-1&&yy[i1]==0)
        for(;dx>=1;dx--)
        {if(dx==ex && dy==ey)
            {if(s<ans)ans=s;
            return;}
            if(aaa[dx][dy])break;}}
    if(xx[i1]==1&&yy[i1]==0)
        for(;dx<=r;dx++)
        {if(dx==ex && dy==ey)
            {if(s<ans)ans=s;
            return;}
        if(aaa[dx][dy])break;}
    if(xx[i1]==0&&yy[i1]==1)
        for(;dy<=c;dy++)
        {if(dx==ex && dy==ey)
            {if(s<ans)ans=s;
            return;}
            if(aaa[dx][dy])break;}
    if(xx[i1]==0&&yy[i1]==-1)
        for(;dy>=1;dy--)
        {if(dx==ex && dy==ey)
            {if(s<ans)ans=s;
            return;}
            if(aaa[dx][dy])break;}
        if(aaa[dx][dy])
        {
            aaa[dx][dy]=0;
            dfs(x,y,s+1);
            aaa[dx][dy]=1;
        }
    }
}
int main()
{int i,j;
while(cin>>c>>r)
{if(c==0&&r==0)break;
    memset(aaa,0,sizeof(aaa));
    for(i=1;i<=r;++i)
        for(j=1;j<=c;++j){
            cin>>aaa[i][j];
if(aaa[i][j]==2){
    sx=i;sy=j;aaa[i][j]=0;}
if(aaa[i][j]==3){
ex=i;ey=j;aaa[i][j]=0;}
}
ans=100000;
dfs(sx,sy,1);
if(ans==100000)cout<<"-1"<<endl;
else cout<<ans<<endl;
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值