搜索(DFS,BFS)

1.计蒜客T1211-红与黑

非常简单经典的DFS

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

char a[21][21];
int ans = 0;
bool vis[21][21];
int w,h;

int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};

void dfs(int x,int y)
{
    ans++;
    vis[x][y] = true;
    for(int i = 0; i < 4; i++){
        int xx = x+dx[i];
        int yy = y+dy[i];
        if(xx<0||xx>h||yy<0||yy>w) continue;
        if(vis[xx][yy]) continue;
        if(a[xx][yy]!='.') continue;
        dfs(xx,yy);
    }
}

int main()
{
    int x=0,y=0;
    cin >>w>>h;
    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            cin >>a[i][j];
            if(a[i][j]=='@') x=i,y=j;
        }
    }
    dfs(x,y);
    cout << ans;
	return 0;
}

2.计蒜客T1212 仙岛求药

求最短距离-BFS 也是常规套路简单题

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int m,n;
char g[21][21];
bool vis[21][21];
int ans = 0;

struct node
{
    int x,y;
    int step;//不用记录该点的符号,用g[v.x][v.y]即可求得
    node(){}
    node(int x,int y,int step):x(x),y(y),step(step){}
};

int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};

int bfs(int x,int y,int s,int t)
{
    queue<node> q;
    q.push(node(x,y,0));
    node e,v;
    while(!q.empty()){
        e = q.front();
        q.pop();

        for(int i = 0; i < 4; i++){
            v.x = e.x+dx[i];
            v.y = e.y+dy[i];
            v.step = e.step + 1;
            //搜索到终点
            if(v.x==s&&v.y==t){
                return v.step;
            }
            //判断出界
            if(v.x<0||v.x>=m||v.y<0||v.y>=n) continue;//边界判断错误写成v.x<m,v.y>n导致少过3组样例
            if(vis[v.x][v.y]) continue;
            //标记该点并继续搜索
            vis[v.x][v.y] = true;
            q.push(v);
        }
    }
    return -1;

}


int main()
{
    int x=0,y=0,s=0,t=0;
    cin >>m>>n;
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            cin >>g[i][j];
            if(g[i][j]=='@') x=i,y=j;
            if(g[i][j]=='*') s=i,t=j;
            if(g[i][j]=='#') vis[i][j] = true;
        }
    }
    cout << bfs(x,y,s,t);
	return 0;
}

3.计蒜客T1213拯救行动

用优先队列即可;注意重载<的两种方式

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int n,m;
char g[201][201];
bool vis[201][201];
int rx,ry,ax,ay;

struct node
{
    int x,y;
    int step;//不用记录该点的符号,用g[v.x][v.y]即可求得
    node(){}
    node(int x,int y,int step):x(x),y(y),step(step){}
    bool operator < (const node& e)const
    {
        return step > e.step;
    }
//    friend bool operator < (const node& a, const node& b)
//    {
//        return a.step > b.step;
//    }
};

int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};

int bfs()
{
    priority_queue<node> q;
    q.push(node(rx,ry,0));
    vis[rx][ry] = true;
    node e,v;
    while(!q.empty()){
        e = q.top();
        q.pop();

        for(int i = 0; i < 4; i++){
            v.x = e.x+dx[i];
            v.y = e.y+dy[i];
            v.step = e.step + 1;
            //搜索到终点
            if(v.x==ax&&v.y==ay){
                return v.step;
            }
            //判断出界
            if(v.x<0||v.x>=n||v.y<0||v.y>=m) continue;
            if(vis[v.x][v.y]) continue;
            //标记该点并继续搜索
            if(g[v.x][v.y]=='x') v.step++;
            vis[v.x][v.y] = true;
            q.push(v);
        }
    }
    return -1;

}


int main()
{
    cin >>n>>m;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> g[i][j];
            if(g[i][j]=='r') rx=i,ry=j;
            if(g[i][j]=='a') ax=i,ay=j;
            if(g[i][j]=='#') vis[i][j] = true;
        }
    }
    int ans = bfs();
    if(ans==-1) cout << "Impossible";
    else cout << ans;
	return 0;
}

4.蓝桥杯剪格子

关键在于回溯

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int m,n;
int a[11][11];
int ans = 0,tot = 0;
bool vis[11][11];

int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};

void dfs(int x,int y,int cnt,int sum)
{
//    printf("(%d,%d) cnt=%d sum=%d\n",x,y,cnt,sum);
    if(sum*2==tot){
        ans = cnt;
        return;
    }
    if(sum*2>tot) return;
    for(int i = 0; i < 4; i++){
        int xx = x + dx[i];
        int yy = y + dy[i];

        if(xx<0||xx>=n||yy<0||yy>=m) continue;
        if(vis[xx][yy]) continue;
        vis[xx][yy] = true;
        dfs(xx,yy,cnt+1,sum+a[xx][yy]);
        vis[xx][yy] = false;//关键:回溯
    }
}


int main()
{
    cin >>m>>n;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >>a[i][j];
            tot += a[i][j];
        }
    }
//    printf("tot=%d\n",tot);
    dfs(0,0,1,a[0][0]);
    cout << ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_36313227/article/details/88761743