Kuangbin专题一简单搜索

kuangbin专题一简单搜索

棋盘问题 POJ - 1321

深搜题,注意的是剪枝——剩下的格子不够了就return。
单开两个一位数组记录挺方便,没有习惯性map。

#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
typedef pair<int, int> P;
#define rep(i, ll, nn) for(int i = (ll); i <= (nn); i++)
#define N 10

char maze[N][N];
int n, k, num;
char c;
int cnt;
bool ux[N], uy[N];

bool ok(int x, int y)
{
    return (!ux[x] && !uy[y] && maze[x][y] == '#');
}

void dfs(int x, int left)
{
    if(left == 0){
        cnt++;
        return;
    }

    if(n - x < left || x == n + 1) return;

    rep(j, 1, n){
        if(ok(x + 1, j)){
            ux[x + 1] = uy[j] = true;
            dfs(x + 1, left - 1);
            ux[x + 1] = uy[j] = false;
        }
    }

    dfs(x + 1, left);
}

int main()
{
    while(scanf("%d%d", &n, &k) != EOF && n > 0){
        rep(i, 1, n) rep(j, 1, n) cin >> maze[i][j];

        cnt = 0;
        dfs(0, k);

        printf("%d\n", cnt);
    }

    return 0;
}

Dungeon Master POJ - 2251

三维的宽搜,其他都是一样的裸的板子。

#include <queue>
#include <cstdio>
#include <iostream>
#include <utility>
#include <cstring>
#include <vector>
using namespace std;
typedef pair<int, int> P;
#define rep(i, ll, nn) for(int i = (ll); i <= (nn); i++)
#define N 32

struct node{
  int x, y, z;

  node(int a = 1, int b = 1, int c = 1):x(a), y(b), z(c){}
};

int l, r, c;
char maze[N][N][N];
int sx, sy, sz, ex, ey, ez;
int ans;
queue<node> que;
bool used[N][N][N];
int dis[N][N][N];
int dx[] = {0, 0, 1, 0, 0, -1};
int dy[] = {0, 1, 0, 0, -1, 0};
int dz[] = {1, 0, 0, -1, 0, 0};

int bfs()
{
    memset(used, 0, sizeof used);
    memset(dis, 0, sizeof dis);
    while(!que.empty()) que.pop();
    int x, xx, y, yy, z, zz;
    node tmp;
    dis[sx][sy][sz] = 0;
    used[sx][sy][sz] = true;
    que.push(node(sx, sy, sz));

    while(!que.empty()){
        tmp = que.front();que.pop();
        x = tmp.x; y = tmp.y; z = tmp.z;

        if(x == ex && y == ey && z == ez){
            return dis[x][y][z];
        }

        rep(i, 0, 5){
            xx = x + dx[i];yy = y + dy[i];zz = z + dz[i];
            if(xx < 1 || yy < 1 || zz < 1) continue;
            if(xx > l || yy > r || zz > c) continue;
            if(used[xx][yy][zz] || maze[xx][yy][zz] == '#') continue;
            used[xx][yy][zz] = true;
            dis[xx][yy][zz] = dis[x][y][z] + 1;
            que.push(node(xx, yy, zz));
        }
    }

    return -1;
}

int main()
{
    freopen("date.txt", "r", stdin);
    char ch;
    while(scanf("%d%d%d", &l, &r, &c) != EOF && l){
        rep(i, 1, l) rep(j, 1, r) rep(k, 1, c){
            cin >> ch;
            if(ch == 'S'){
                sx = i; sy = j; sz = k;
            }
            else if(ch == 'E'){
                ex = i; ey = j; ez = k;
            }
            maze[i][j][k] = ch;
        }

//rep(i, 1, l) rep(j, 1, r) rep(k, 1, c) {
//    cout << maze[i][j][k];
//    if(k == c) cout << '\n';
//}
        ans = bfs();
        if(ans == -1) printf("Trapped!\n");
        else printf("Escaped in %d minute(s).\n", ans);
    }

    return 0;
}

Catch That Cow POJ - 3278

一维宽搜

#include <queue>
#include <cstdio>
#include <iostream>
#include <utility>
#include <cstring>
#include <vector>
using namespace std;
typedef pair<int, int> P;
#define rep(i, ll, nn) for(int i = (ll); i <= (nn); i++)
#define N 100005

int n, k;
int sx, ex;
int ans;
queue<int> que;
bool used[N];
int dis[N];

int bfs()
{
    if(sx == ex) return 0;

    memset(used, 0, sizeof used);
    memset(dis, 0, sizeof dis);
    while(!que.empty()) que.pop();
    int x, xx;
    dis[sx] = 0;
    dis[ex] = 1000000000;
    used[sx] = true;
    que.push(sx);

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

        rep(i, 0, 2){
            if(i == 0) xx = x * 2;
            if(i == 1) xx = x + 1;
            if(i == 2) xx = x - 1;

            if(xx < 0 || used[xx]) continue;
            if(xx >= ex){
                dis[ex] = min(dis[ex], xx - ex + dis[x] + 1);
                continue;
            }

            used[xx] = true;
            dis[xx] = dis[x] + 1;
            que.push(xx);
        }
    }

    return dis[ex];
}

int main()
{
    //freopen("date.txt", "r", stdin);
    while(scanf("%d%d", &n, &k) != EOF){
        sx = n;ex = k;
        printf("%d\n", bfs());
    }

    return 0;
}

Fliptile POJ - 3279

这题还挺难好像,用二进制数来状态压缩显得很有逼格~~~
解决思想是先枚举第一行的翻法,然后第一行确定了下一行身不由己的要承担起把上一行变换成全白的责任,递推下去看最后一行是不是全白就ok了。
这题既然放在搜索里大概能用搜索写?以后试试。

#include <queue>
#include <cstdio>
#include <iostream>
#include <utility>
#include <cstring>
#include <vector>
using namespace std;
typedef pair<int, int> P;
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)
#define N 17
const int INF = 0x3f3f3f3f;
typedef long long ll;

int m, k, n, num;
int maze[N][N], ans[N][N], out[N][N];
int dx[] = {1, -1, 0, 0, 0};
int dy[] = {0, 0, 1, -1, 0};

int get(int x, int y)
{
    int cnt = maze[x][y];
    rep(i, 0, 4)cnt += ans[x + dx[i]][y + dy[i]];
    return cnt & 1;
}

int solve()
{
    rep(i, 2, m) rep(j, 1, k) ans[i][j] = get(i - 1, j);

    rep(j, 1, k) if(get(m, j)) return -1;

    int cnt = 0;
    rep(i, 1, m) rep(j, 1, k) cnt += ans[i][j];

    return cnt;
}

int main()
{
    //freopen("date.txt", "r", stdin);

    scanf("%d%d", &m, &k);

    rep(i, 1, m) rep(j, 1, k) scanf("%d", &maze[i][j]);

    n = 1 << k;
    num = INF;

    rep(i, 0, n - 1){
        memset(ans, 0, sizeof ans);
        rep(j, 0, k - 1) ans[1][k - j] = i >> j & 1;
        int cnt = solve();
        if(cnt >= 0 && num > cnt){
            num = cnt;
            memcpy(out, ans, sizeof ans);
        }
    }

    if(num == INF) printf("IMPOSSIBLE\n");
    else {
        rep(i, 1, m) rep(j, 1, k) printf("%d%c", out[i][j], j == k?'\n':' ');
    }

    return 0;
}

Find The Multiple POJ - 1426

输入一个数找到它的只有01的倍数。乍一看搜索量极其巨大,然则它的倍数是无限的然而01组成的数是少得多的,所以直接搜01组成的数判断是否是n的倍数就ok。

#include <queue>
#include <cstdio>
#include <iostream>
#include <utility>
#include <cstring>
#include <vector>
using namespace std;
typedef pair<int, int> P;
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)
#define N 17
const int INF = 0x3f3f3f3f;
typedef long long ll;

queue<ll> que;

ll solve(int n)
{
    while(!que.empty()) que.pop();
    que.push(1);
    while(true){
        ll tmp = que.front();que.pop();
        if(tmp % n == 0) return tmp;
        que.push(tmp * 10);
        que.push(tmp * 10 + 1);
    }
}

int main()
{
    int n;
    while(cin >> n && n){
        cout << solve(n) << endl;
    }
    return 0;
}

Shuffle’m Up POJ - 3087

昂模拟题,map,string大法好。

#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef pair<string, string> P;
#define N 101
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

string s1, s2, s12, t1, t2, t12;
int t, c, ans;
map<string, bool> mp;
int main()
{
    scanf("%d", &t);

    rep(Case, 1, t){
        mp.clear();

        scanf("%d", &c);
        cin >> s1 >> s2 >> s12;
        ans = 0;
        t1 = s1;t2 = s2;

        while(true){//printf("%s %s\n", t1, t2);
            ++ans;
            t12.clear();
            rep(i, 0, c - 1){
                t12 += t2[i];t12 += t1[i];
            }
//cout << t1 <<' ' << t2 << endl;
            if(t12 == s12){
                printf("%d %d\n", Case, ans);break;
            }
            else if(mp[t12]){
                printf("%d -1\n", Case);break;
            }

            t1.clear();t2.clear();
            rep(i, 0, c - 1) t1 += t12[i];
            rep(i, c, c * 2 - 1) t2 += t12[i];

            mp[t12] = true;
        }
    }

    return 0;
}

Pots POJ - 3414

记忆路径的宽搜

#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
#include <string>
#include <queue>
using namespace std;
typedef pair<int, int> P;
#define N 101
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

int a, b, c;
string op[6] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
struct opt{
   int d, pa, x, y, z;
   opt(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0):d(a),pa(b),x(c),y(d),z(e){}
}path[N * N];
bool vis[N][N];

int bfs()
{
    int l = 0;
    path[l] = opt(0, -1, 0, 0);
    vis[0][0] = true;

    queue<opt> que;
    que.push(opt(1, l - 1, a, 0, 0));
    que.push(opt(1, l - 1, 0, b, 1));

    while(!que.empty()){
        path[l] = que.front();que.pop();
        opt & q = path[l];

        if(q.x == c || q.y == c){
            return l;
        }

        if(q.x != a && !vis[a][q.y]){
            vis[a][q.y] = true; que.push(opt(q.d + 1, l, a, q.y, 0));
        }
        if(q.y != b && !vis[q.x][b]){
            vis[q.x][b] = true; que.push(opt(q.d + 1, l, q.x, b, 1));
        }
        if(q.x != 0 && !vis[0][q.y]){
            vis[0][q.y] = true; que.push(opt(q.d + 1, l, 0, q.y, 2));
        }
        if(q.y != 0 && !vis[q.x][0]){
            vis[q.x][0] = true; que.push(opt(q.d + 1, l, q.x, 0, 3));
        }
        int k = min(q.x, b - q.y);
        if(k > 0 && !vis[q.x - k][q.y + k]){
            vis[q.x - k][q.y + k] = true;
            que.push(opt(q.d + 1, l, q.x - k, q.y + k, 4));
        }
        k = min(a - q.x, q.y);
        if(k > 0 && !vis[q.x + k][q.y - k]){
            vis[q.x + k][q.y - k] = true;
            que.push(opt(q.d + 1, l, q.x + k, q.y - k, 5));
        }

        l++;
    }

    return -1;
}

int main()
{
    cin >> a >> b >> c;

    int t = bfs();

    if(t == -1) printf("impossible\n");
    else{
        cout << path[t].d << endl;
        int ans[N * N], l = 0;
        ans[l++] = path[t].z;
        while(path[t].pa != -1){
            t = path[t].pa;
            ans[l++] = path[t].z;
           // cout << path[t].x << ' ' << path[t].y << endl;
        }
        for(int i = l - 2; i >= 0; i--)
            cout << op[ans[i]] << endl;
    }

    return 0;
}

Prime Path POJ - 3126

老老实实宽搜

#include <queue>
#include <cstdio>
#include <iostream>
#include <utility>
#include <cstring>
#include <vector>
#include <map>
using namespace std;
typedef pair<int, int> P;
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)
#define N 17
const int INF = 0x3f3f3f3f;
typedef long long ll;

bool pri[10000];
queue<P> que;
map<P, int> ans;
bool vis[10000];

int change(int s, int d, int to)
{
    if(d == 1) return (s / 10) * 10 + to;
    else if(d == 2) return (s / 100) * 100 + to * 10 + s % 10;
    else if(d == 3) return (s / 1000) * 1000 + to * 100 + s % 100;
    else return to * 1000 + s % 1000;
}

int solve(int s, int e)
{
    while(!que.empty()) que.pop();
    que.push(P(s, 0));
    P h;
    int t;
    vis[s] = true;

    while(!que.empty()){
        h = que.front();que.pop();
        if(h.first == e) return h.second;
        if(h.second > 10) continue;
        rep(i, 1, 4) rep(j, 0, 9) {
            t = change(h.first, i, j);
            if(t != h.first && pri[t] && t > 1000 && !vis[t]){
                vis[t] = true;
                que.push(P(t, h.second + 1));
            }
        }
    }
}

int main()
{
    int s, e, t;
    memset(pri, true, sizeof pri);

    rep(i, 2, 5000) if(pri[i]){
        for(int j = i * 2; j < 10000; j += i)
            pri[j] = false;
    }
//cout << pri[19] << endl;
    cin >> t;
    while(t--){
        cin >> s >> e;
        memset(vis, 0, sizeof vis);
        int ans = solve(s, e);
        if(ans == -1) printf("Impossible\n");
        else printf("%d\n", ans);
    }

    return 0;
}

Fire Game FZU - 2150

为了特殊的游戏要有合适的场地,要把草少了,要烧得快。枚举任意两个点来宽搜。


#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
#include <string>
#include <queue>
using namespace std;
typedef pair<int, int> P;
#define N 11
#define f first
#define s second
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

char maze[N][N];
int n, m;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int d[N][N];
bool vis[N][N];

int bfs(int x1, int y1, int x2, int y2)
{
    memset(d, 0, sizeof d);
    memset(vis, false, sizeof vis);
    queue<P> que;
    que.push(P(x1, y1));
    d[x1][y1] = 0;
    vis[x1][y1] = true;
    if(maze[x2][y2] == '#' && !vis[x2][y2]){
        que.push(P(x2, y2));
        d[x2][y2] = 0;
        vis[x2][y2] = true;
    }

    while(!que.empty()){
        P h = que.front(); que.pop();

        for(int i = 0; i < 4; i++){
            int x = h.f + dx[i], y = h.s + dy[i];
            if(x < 0 || x >= n || y < 0 || y >= m) continue;
            if(maze[x][y] == '.' || vis[x][y]) continue;
            vis[x][y] = true;
            que.push(P(x, y));
            d[x][y] = d[h.f][h.s] + 1;
        }
    }

    rep(i, 0, n - 1) rep(j, 0, m - 1) if(maze[i][j] == '#' && !vis[i][j]) return -1;
    int cnt = -1;
    rep(i, 0, n - 1) rep(j, 0, m - 1) cnt = max(cnt, d[i][j]);
    return cnt;
}

int main()
{
    int t;

    scanf("%d", &t);

    rep(Case, 1, t){
        scanf("%d%d", &n, &m);
        rep(i, 0, n - 1) scanf("%s", maze[i]);
        int ans = -1;
        rep(i, 0, n - 1) rep(j, 0, m - 1) rep(k, 0, n - 1) rep(l, 0, m - 1){
            if(maze[i][j] == '#' && maze[k][l] == '#'){
                int t = bfs(i, j, k, l);
                if(t >= 0 && (ans == -1 || ans > t)) ans = t;//cout << i << ' ' << j << ' ' << k <<' ' << l << endl;
            }
        }
        printf("Case %d: %d\n", Case, ans);
    }

    return 0;
}

Fire! UVA - 11624

分两次搜,第一次预处理出火烧的时间,第二次搜人。
mmp我把d初始化成-1最后比较的时候忘了特判。初始化INF就不会这样了。

#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
#include <string>
#include <queue>
using namespace std;
typedef pair<int, int> P;
#define N 1001
#define fi first
#define se second
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

int n, m, ans;
char maze[N][N];
int d[N][N], flee[N][N];
bool vis[N][N];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
queue<P> que;

void bfs(int tpe)
{
    memset(vis, false, sizeof vis);
    while(!que.empty()) que.pop();
    if(tpe == 1){
        memset(d, -1, sizeof d);
        rep(i, 0, n - 1) rep(j, 0, m - 1) if(maze[i][j] == 'F') {
            que.push(P(i, j)); d[i][j] = 0; vis[i][j] = true;
        }
    }
    else{
        ans = -1;  memset(flee, 0, sizeof flee);
        rep(i, 0, n - 1) rep(j, 0, m - 1) if(maze[i][j] == 'J'){
            que.push(P(i, j)); flee[i][j] = 0; vis[i][j] = true; break;
        }
    }

    while(!que.empty()){
        P h = que.front(); que.pop();

        if(tpe == 2)
        if(h.fi == 0 || h.fi == n - 1 || h.se == 0 || h.se == m - 1){//printf("x %d y %d\n", h.fi, h.se);
            ans = flee[h.fi][h.se] + 1; break;
        }

        rep(i, 0, 3){
            int x = h.fi + dx[i], y = h.se + dy[i];
            if(x < 0 || x >= n || y < 0 || y >= m) continue;
            if(maze[x][y] == '#' || vis[x][y]) continue;
            if(tpe == 2 && d[x][y] != -1 && flee[h.fi][h.se] + 1 >= d[x][y]) continue;

            if(tpe == 1) d[x][y] = d[h.fi][h.se] + 1;
            else flee[x][y] = flee[h.fi][h.se] + 1;
            vis[x][y] = true;
            que.push(P(x, y));
        }
    }
}

int main()
{
   // freopen("data.txt", "r", stdin);
    int t;

    scanf("%d", &t);

    while(t--){
        scanf("%d%d", &n, &m);
        rep(i, 0, n - 1) scanf("%s", maze[i]);

        bfs(1);//rep(i, 0, n - 1) rep(j, 0, m - 1) printf("%d%c", d[i][j], j == m - 1?'\n':' ');
        bfs(2);

        if(ans == -1) printf("IMPOSSIBLE\n");
        else printf("%d\n", ans);
    }

    return 0;
}

迷宫问题 POJ - 3984

宽搜记忆路径

#include <string>
#include <queue>
#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
using namespace std;
typedef pair<int, int> P;
#define N 5
#define fi first
#define se second
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

int maze[N][N];
P path[N][N];
int d[N][N];
queue<P> que;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

void bfs()
{
    memset(d, 0x3f, sizeof d);
    que.push(P(0, 0));
    d[0][0] = 0;

    while(!que.empty()){
        P h = que.front(); que.pop();

        if(h.fi == 4 && h.se == 4) return;

        rep(i, 0, 3){
            int x = h.fi + dx[i], y = h.se + dy[i];
            if(x < 0 || x >= N || y < 0 || y >= N) continue;
            if(maze[x][y] == 1) continue;
            if(d[x][y] <= d[h.fi][h.se] + 1) continue;

            d[x][y] = d[h.fi][h.se] + 1;
            path[x][y] = h;
            que.push(P(x, y));
        }
    }
}

int main()
{
    //freopen("data.txt", "r", stdin);
    rep(i, 0, 4) rep(j, 0, 4) scanf("%d", &maze[i][j]);

    bfs();
    P ans[N * N];
    int l = 0;
    ans[l++] = P(4, 4);
    int x = 4, y = 4;
    while(!(x == 0 && y == 0)){
        ans[l++] = path[x][y];
        x = ans[l - 1].fi; y = ans[l - 1].se;
    }
    for(int i = l - 1; i >= 0; i--)
        printf("(%d, %d)\n", ans[i].fi, ans[i].se);

    return 0;
}

Oil Deposits HDU - 1241

深搜求连通度。我第一道深搜题就是这个题型,亲切。

#include <string>
#include <queue>
#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
using namespace std;
typedef pair<int, int> P;
#define N 101
#define fi first
#define se second
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

char maze[N][N];
int n, m;
int cnt;
int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};
int dy[] = {1, -1, 0, 0, 1, -1, 1, -1};

void dfs(int x, int y)
{
    maze[x][y] = '*';
    rep(i, 0, 7) {
        int xx = x + dx[i], yy = y + dy[i];
        if(xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
        if(maze[xx][yy] == '*') continue;
        dfs(xx, yy);
    }
}

int main()
{
    //freopen("data.txt", "r", stdin);

    while(~scanf("%d%d", &n, &m) && n){
        rep(i, 0, n - 1) scanf("%s", maze[i]);

        cnt = 0;
        rep(i, 0, n - 1) rep(j, 0, m - 1) if(maze[i][j] == '@'){
            dfs(i, j);
            cnt++;
        }

        printf("%d\n", cnt);
    }

    return 0;
}

非常可乐 HDU - 1495

重复代码的复制要谨慎。。。

#include <string>
#include <queue>
#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
using namespace std;
//typedef pair<int, int> P;
#define N 101
#define fi first
#define se second
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

struct P{
  int a, b, c;
  P (int x=0, int y=0, int z=0):a(x), b(y), c(z){}
  bool judge(){
      return (a == b && c == 0) || (b == c && a == 0) || (c == a && b == 0);
  }
  bool operator < (P t) const{
      if(a == t.a) {
        if(b == t.b)
          return c < t.c;
        return b < t.b;
      }
      return a < t.a;
  }
};
map<P, int> d;
queue<P> que;

int bfs(int n, int m, int z)
{
    d.clear();
    while(!que.empty()) que.pop();
    int dif;

    que.push(P(n, 0, 0));
    d[P(n, 0, 0)] = 0;

    while(!que.empty()){
        P h = que.front(); que.pop();

        if(h.judge()) return d[h];
//if(n == 4)printf("%d %d %d\n", h.a, h.b, h.c);
        if(h.a != 0 && h.b < m){
            dif = min(h.a, m - h.b);
            P tmp = P(h.a - dif, h.b + dif, h.c);
            if(!d[tmp]) d[tmp] = d[h] + 1, que.push(tmp);
        }

        if(h.a != 0 && h.c < z){
            dif = min(h.a, z - h.c);
            P tmp = P(h.a - dif, h.b, h.c + dif);
            if(!d[tmp]) d[tmp] = d[h] + 1, que.push(tmp);
        }

        if(h.b != 0 && h.c < z){
            dif = min(h.b, z - h.c);
            P tmp = P(h.a, h.b - dif, h.c + dif);
            if(!d[tmp]) d[tmp] = d[h] + 1, que.push(tmp);
        }

        if(h.b != 0 && h.a < n){
            dif = min(n - h.a, h.b);
            P tmp = P(h.a + dif, h.b - dif, h.c);
            if(!d[tmp]) d[tmp] = d[h] + 1, que.push(tmp);
        }

        if(h.c != 0 && h.a < n){
            dif = min(h.c, n - h.a);
            P tmp = P(h.a + dif, h.b, h.c - dif);
            if(!d[tmp]) d[tmp] = d[h] + 1, que.push(tmp);
        }

        if(h.c != 0 && h.b < m){
            dif = min(h.c, m - h.b);
            P tmp = P(h.a, h.b + dif, h.c - dif);
            if(!d[tmp]) d[tmp] = d[h] + 1, que.push(tmp);
        }
    }

    return -1;
}

int main()
{
    //freopen("data.txt", "r", stdin);

    int a, b, c, ans;
    while(~scanf("%d%d%d", &a, &b, &c) && a + b + c){
        if((ans = bfs(a, b, c)) == -1) puts("NO");
        else printf("%d\n", ans);
    }

    return 0;
}

Find a way HDU - 2612

又是搜两次。

#include <string>
#include <queue>
#include <cstdio>
#include <cstring>
#include <utility>
#include <iostream>
#include <map>
using namespace std;
typedef pair<int, int> P;
#define N 201
#define fi first
#define se second
#define rep(i, lll, nnn) for(int i = (lll); i <= (nnn); i++)

char maze[N][N];
P Y, M;
map<P, bool> mp;
int d1[N][N], d2[N][N];
bool vis[N][N];
queue<P> que;
int n, m;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int bfs()
{
    while(!que.empty()) que.pop();
    memset(vis, false, sizeof vis);
    memset(d1, 0x3f, sizeof d1);
    que.push(Y);
    d1[Y.fi][Y.se] = 0;
    int cnt = 0;
    vis[Y.fi][Y.se] = true;
    while(!que.empty()){
        P h = que.front(); que.pop();
        if(mp[h]) cnt++;
        if(cnt == mp.size()) break;
        rep(i, 0, 3){
            int x = h.fi + dx[i], y = h.se + dy[i];
            if(x < 0 || x >= n || y < 0 || y >= m) continue;
            if(vis[x][y] || maze[x][y] == '#') continue;

            d1[x][y] = d1[h.fi][h.se] + 1;
            vis[x][y] = true;
            que.push(P(x, y));
        }
    }

    while(!que.empty()) que.pop();
    memset(vis, false, sizeof vis);
    memset(d2, 0x3f, sizeof d2);
    que.push(M);
    d2[M.fi][M.se] = 0;
    cnt = 0;
    vis[M.fi][M.se] = true;
    while(!que.empty()){
        P h = que.front(); que.pop();
        if(mp[h]) cnt++;
        if(cnt == mp.size()) break;
        rep(i, 0, 3){
            int x = h.fi + dx[i], y = h.se + dy[i];
            if(x < 0 || x >= n || y < 0 || y >= m) continue;
            if(vis[x][y] || maze[x][y] == '#') continue;

            d2[x][y] = d2[h.fi][h.se] + 1;
            vis[x][y] = true;
            que.push(P(x, y));
        }
    }

    map<P, bool>::iterator it;
    int ans = 9999999;
    for(it = mp.begin(); it != mp.end(); it++){
        if(!it->se) continue;
        int x = it->fi.fi, y = it->fi.se;
        ans = min(d1[x][y] + d2[x][y], ans);
    }
//printf("cnt %d\n", cnt);
//if(mp[P(0, 3)]) printf("%d %d\n", d1[0][3], d2[0][3]);
//if(mp[P(3, 0)]) printf("%d %d %d\n", d1[3][0], d2[3][0], (int)mp.size());
    return ans * 11;
}

int main()
{
   // freopen("data.txt", "r", stdin);

    while(~scanf("%d%d", &n, &m)){
        rep(i, 0, n - 1) scanf("%s", maze[i]);

        mp.clear();
        rep(i, 0, n - 1) rep(j, 0, m - 1) {
            if(maze[i][j] == 'Y') Y = P(i, j);
            else if(maze[i][j] == 'M') M = P(i, j);
            else if(maze[i][j] == '@') mp[P(i, j)] = 1;
        }

        printf("%d\n", bfs());
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值