其他分享
首页 > 其他分享> > 【kuangbin专题】01——简单搜索

【kuangbin专题】01——简单搜索

作者:互联网

【kuangbin专题】01——简单搜索

https://www.acwing.com/activity/content/90/
目录:

1. 棋盘问题

普通dfs问题,注意回溯。
dfs问题就是每种方案都try一下,一直莽到头,然后再挨个回头(回溯)

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int n, k;
ll cnt, res;
char a[10][10];
bool vis[10];

void dfs (int x) {
    if (res == 0)       {cnt ++; return ;}
    if (x == n + 1)     return ;
    for (int i = 1; i <= n; i ++) {
        if (vis[i] || a[x][i] == '.')  continue;
        vis[i] = true;
        res --;
        dfs (x + 1);
        vis[i] = false;
        res ++;
    }
    dfs (x + 1);
}

int main () {
    while (cin >> n >> k, (n+1)||(k+1)) {
        memset (vis, false, sizeof vis);
        cnt = 0, res = k;
        for (int i = 1; i <= n; i ++)
            for (int j = 1; j <= n; j ++)
                cin >> a[i][j];
        dfs (1);
        cout << cnt << endl;
    }
}

2. 地牢大师

简单bfs,不同的是坐标是3维的,开三维数组即可

#include <bits/stdc++.h>

using namespace std;
const int N = 105;
char a[N][N][N];
int d[N][N][N];
int l, r, c, sx, sy, sz;

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

struct Node {
    int x, y, z;
};

bool Range (int x, int y, int z) {
    if (x > l || x <= 0 || y > r || y <= 0 || z > c || z <= 0)
        return false;
    return true;
}

void bfs () {
    memset (d, 0x3f, sizeof d);
    queue <Node> q;
    q.push ({sx, sy, sz});
    d[sx][sy][sz] = 0;

    while (!q.empty ()) {
        auto t = q.front ();
        q.pop();
        int x = t.x, y = t.y, z= t.z;

        for (int i = 0; i < 6; i ++) {
            int xx = x + dx[i], yy = y + dy[i], zz = z + dz[i];
            if (!Range (xx, yy, zz) || d[xx][yy][zz] != 0x3f3f3f3f || a[xx][yy][zz] == '#') continue;
            d[xx][yy][zz] = d[x][y][z] + 1;
            q.push ({xx, yy, zz});
            if (a[xx][yy][zz] == 'E') {
                cout << "Escaped in " << d[xx][yy][zz] << " minute(s)." << endl;
                return ;
            }
        }
    }
    cout << "Trapped!" << endl;
}

int main () {
    while (cin >> l >> r >> c, l || r || c) {
        for (int i = 1; i <= l; i ++)
            for (int j = 1; j <= r; j ++)
                for (int k = 1; k <= c; k ++) {
                    cin >> a[i][j][k];
                    if (a[i][j][k] == 'S')  sx =  i, sy = j, sz = k;
                }
                    
        bfs ();

    }

}

3. 抓住那头牛

也是套路化的bfs,把三种操作视为状态,存入dx[]即可

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 5;
int d[N];
int st, ed;

bool Range (int x) {
    if (x < 0 || x > 1e5)   return false;
    return true;
}

void bfs () {
    memset (d, 0x3f, sizeof d);
    d[st] = 0;
    queue <int> q;
    q.push (st);

    while (!q.empty ()) {
        int x = q.front ();
        q.pop();

        int dx[] = {-1, 1, x};
        for (int i = 0; i < 3; i ++) {
            int xx = x + dx[i];
            if (!Range (xx) || d[xx] != 0x3f3f3f3f) continue;
            d[xx] = d[x] + 1;
            q.push (xx);
            if (xx == ed) {
                cout << d[xx] << endl;
                return ;
            }
        }
    }
}

int main () {
    cin >> st >> ed;
    if (st == ed) {
        cout << 0 << endl;
        return 0;
    }
    bfs ();

}


//bfs经典模型

4. 翻转

个人觉得初接触有点难理解
逻辑:枚举每一种方案,第一行只能靠改变自身;然后依次通过后面的来改变前面的,最后check最后一行是否满足条件(满足则记录为一种方案)
。。。感觉还有些抽象,我建议多模拟几遍代码,代入数据在草稿纸上演算。。因为我也看了好多遍的

对了,还涉及一些位运算的知识,记得滚回去复习

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
const int N = 20;
int n, m;
char a[N][N], b[N][N];//备用图(在这上面改动) 原图(不变的)
int ans[N][N], tmp[N][N]; //最终方案 临时方案
int dx[] = {0, 1, 0, -1, 0}, dy[] = {0, 0, 1, 0, -1};

bool Range (int x, int y) {
    if (x < 0 || x >= n || y < 0 || y >= m)
        return false;
    return true;
}

void change (int x, int y) {
    for (int i = 0; i < 5; i ++) {
        int xx = x + dx[i], yy = y + dy[i];
        if (Range (xx, yy))     a[xx][yy] ^= 1;
    }
    tmp[x][y] = 1;
}

void dfs () {
    int cnt = 0x3f3f3f3f;
    for (int _ = 0; _ <  1 << m; _ ++) {
        int step = 0;
        memset (tmp, 0, sizeof tmp); //方案置0
        memcpy (a, b, sizeof b); //backup, a=b

        for (int i = 0; i < m; i ++) {
            if (_ >> i & 1) { //保证字典序最小
                step ++;
                change (0, i);
            }
        }

        for (int i = 1; i < n; i ++)
            for (int j = 0; j < m; j ++) {
                if (a[i-1][j] == '1') { //根据上一行的情况来改变本行
                    step ++;
                    change (i, j);
                }
            }

        bool suc = true;
        for (int i = 0; i < m; i ++) {
            if (a[n-1][i] == '1') {
                suc = false;
                break;
            }
        }

        if (suc && step < cnt) {
            cnt  = step;
            memcpy (ans, tmp, sizeof tmp);
        }
    }

    if (cnt == 0x3f3f3f3f)  cout << "IMPOSSIBLE\n";
    else {
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < m; j ++)
                cout << ans[i][j] << ' ';
            cout << endl;
        }
    }
}

int main () {
    cin >> n >> m;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++)
            cin >> b[i][j];

    dfs  ();
   
}
//dfs + 记录方案

后面的吃完饭来更。。dfs真是烦死人了!!

标签:专题,int,dfs,yy,++,xx,01,dx,kuangbin
来源: https://www.cnblogs.com/CTing/p/16437990.html