复习 [kuangbin带你飞]专题1 简单搜索

https://vjudge.net/article/187

1. poj 1321 棋盘问题

  • 一行一行的放,这一行也可以不放,放在下一行再放,放过的列数要标记
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
int vis[MAXN];
char mp[20][20];
int ans = 0;
int n, k;
void Dfs(int now, int y){
    if(now == k){
        ans += 1;
        return;
    }
    if(y == n + 1) return;
    for(int i=1;i<=n;i++){
        if(!vis[i] && mp[y][i] == '#'){
            vis[i] = 1;
            Dfs(now + 1, y + 1);
            vis[i] = 0;
        }
    }
    Dfs(now, y + 1);
}
int main(){
    #ifdef LOCAL
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    while(cin >> n >> k){
        if(n == -1 && k == -1) break;
        ans = 0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin >> mp[i][j];
            }
        }
        Dfs(0, 1);
        cout << ans << '\n';
    }
    return 0;
}

2. poj 2251 Dungeon Master

  • 注意输入的顺序,常规 b f s bfs bfs找最短路径
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
char a[40][40][40];
struct Node{
    int x, y, z, ans;
};
int L, R, C;
int xx[] = {0, 0, 0, 0, 1, -1};
int yy[] = {0, 0, -1, 1, 0, 0};
int zz[] = {1, -1, 0, 0, 0, 0};
void bfs(int x1, int y1, int z1){
    queue<Node> q;
    q.push(Node{x1, y1, z1, 0});
    a[x1][y1][z1] = '#';
    while(!q.empty()){
        Node u = q.front();
        q.pop();
        if(a[u.x][u.y][u.z] == 'E'){
            cout << "Escaped in " << u.ans << " minute(s).\n";
            return;
        }
        for(int i=0;i<6;i++){
            int dx = u.x + xx[i];
            int dy = u.y + yy[i];
            int dz = u.z + zz[i];
            if(dx < 1 || dy < 1 || dz < 1 || dx > L || dy > R || dz > C || a[dx][dy][dz] == '#') continue;
            if(a[dx][dy][dz] == 'E'){
                cout << "Escaped in " << u.ans + 1 << " minute(s).\n";
                return;
            }
            a[dx][dy][dz] = '#';
            q.push(Node{dx, dy, dz, u.ans + 1});
        }
    }
    cout << "Trapped!" << '\n';
}
int main(){
    #ifdef LOCAL
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    while(cin >> C >> L >> R){
        if(L == 0 && R == 0 && C == 0) break;
        int x1, y1, z1, x2, y2, z2;
        x1 = y1 = z1 = x2 = y2 = z2 = -1;
        for(int k=1;k<=C;k++){
            for(int i=1;i<=L;i++){
                for(int j=1;j<=R;j++){
                    cin >> a[i][j][k];
                    if(a[i][j][k] == 'S'){
                        x1 = i;
                        y1 = j;
                        z1 = k;
                    }
                }
            }
        }
        bfs(x1, y1, z1);
    }
    return 0;
}

3. poj 3278 Catch That Cow

  • **题,注意标记已经走过的状态,数组别越界
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 1e6 + 100;
int vis[MAXN];
struct st{
    int val;
    int ans;
};
int bfs(){
    int n, k;
    cin >> n >> k;
    if(k <= n){
        return n - k;
    }
    queue<st> q;
    st x;
    x.ans = 0;
    x.val = n;
    q.push(x);
    while(!q.empty()){
        st u = q.front();
        q.pop();
        int a = u.val - 1;
        int b = u.val + 1;
        int c = u.val * 2;
        if(a == k || b == k || c == k){
            return u.ans + 1;
        }
        if(b >= 0 && !vis[b]){
            vis[b] = 1;
            x.val = b;
            x.ans = u.ans + 1;
            q.push(x);
        }
        if(c < MAXN && c >= 0 && !vis[c]){
            vis[c] = 1;
            x.val = c;
            x.ans = u.ans + 1;
            q.push(x);
        }
        if(a >= 0 && !vis[a]){
            vis[a] = 1;
            x.val = a;
            x.ans = u.ans + 1;
            q.push(x);
        }
    }
    return -1;
}
int main(){
    cout << bfs();
    return 0;
}

4. poj 3279 Fliptile

  • 这道题只要想到了先确定第一行,那就不难了,第一行我们用二进制枚举每一个状态,很常规的操作,这样确保最后按照字典序输出,因为每次的枚举,第一行能够唯一确定,所以最后的答案也是唯一确定的
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
int a[MAXN];
int mp[20][20];
int mp2[20][20];
int ans[20][20];
void change(int x, int y){
    mp2[x - 1][y] ^= 1;
    mp2[x + 1][y] ^= 1;
    mp2[x][y] ^= 1;
    mp2[x][y + 1] ^= 1;
    mp2[x][y - 1] ^= 1;
}
void print(int m, int n){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            cout << ans[i][j] << ' ';
        }cout << '\n';
    }
}
void solve(int m, int n){
    for(int k=0;k<(1<<n);k++){
        memcpy(mp2, mp, sizeof mp);
        memset(ans, 0, sizeof ans);
        for(int j=1;j<=n;j++){
            if(k & (1 << (j - 1))){
                change(1, j);
                ans[1][j] = 1;
            }
        }
        for(int i=2;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(mp2[i - 1][j]){
                    change(i, j);
                    ans[i][j] = 1;
                }
            }
        }
        for(int j=1;j<=n;j++){
            if(mp2[m][j]) break;
            if(j == n){
                print(m, n);
                return;
            }
        }
    }
    cout << "IMPOSSIBLE";
}
int main(){
    #ifdef LOCAL
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int m, n;
    cin >> m >> n;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            cin >> mp[i][j];
        }
    }
    solve(m, n);
    return 0;
}

5. poj 1426 Find The Multiple

  • 暴力,可以先打出来200个看一看对不对,都是由1和0组成的就对了
  • 要是T了就换G++编译器
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <iomanip>
#include <climits>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
int a[MAXN];
ll bfs(ll n){
    queue<ll> q;
    q.push(1);
    while(!q.empty()){
        ll u = q.front();
        q.pop();
        if(u % n == 0) return u;
        q.push(u * 10);
        q.push(u * 10 + 1);
    }
    return -1;
}
int main(){
    #ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll n;
    vector<ll> ans(201);
    for(ll i=1;i<=200;i++){
        ans[i] = bfs(i);
    }
    while(cin >> n && n){
        cout << ans[n] << '\n';
    }
    return 0;
}

6. poj 3126 Prime Path

发现两年前做过了,应该很简单吧,下面是当时写的

#include <iostream>
#include <queue>
#include <cstring>
#define maxn 5
int step[10000+maxn],vis[10000+maxn]; 
int prime[10000+maxn];
using namespace std;
bool Is_prime(int n){
    if(n==2) return true;
    if(n==1||n%2==0) return false;
    for(int i=3;i<n;i+=2){
        if(n%i==0) return false;
    }
    return true;
}
void init(){
    for(int i=1000;i<10000;i++){
        if(Is_prime(i)) prime[i]=1;
    }
}
int BFS(int dx,int dy){
    queue<int> q;
    int a[10];
    q.push(dx);
    memset(step,0,sizeof(step));
    memset(vis,0,sizeof(vis));
    vis[dx]=1;
    while(!q.empty()){
        int x=q.front();
        q.pop();
        if(x==dy) return step[dy];
        a[0]=x%10;a[1]=x%100/10;a[2]=x%1000/100;a[3]=x/1000;
        for(int i=0;i<4;i++){
            int num=a[i];
            for(int iu=0;iu<10;iu++){
                if(iu!=num){
                    a[i]=iu;
                    int temp=a[0]+10*a[1]+100*a[2]+1000*a[3];
                    if(prime[temp]&&!vis[temp]){
                        step[temp]=step[x]+1;
                        vis[temp]=1;
                        q.push(temp);
                    }
                }
            }
            a[i]=num;
        }
    }
    return -1;
}
int main(){
    init();
    int T;
    int dx,dy;
    cin>>T;
    while(T--){
        cin>>dx>>dy;
        int ret=BFS(dx,dy);
        if(ret==-1) cout<<"Impossible";
        else cout<<ret<<endl;
    }
    //system("pause");
    return 0;
}

7. poj 3087 Shuffle’m Up

  • 三行字符串,表示从底到顶的颜色,第一行是 S 1 S_1 S1,第二行是 S 2 S_2 S2,第三行是目标,每次按照图示洗牌完毕截取下面的 C C C个作为新的 S 1 S_1 S1,上面作为新的 S 2 S_2 S2,重复操作下去,问多少次操作能达到目标或者永远也达不到
  • 题读懂了以后直接模拟即可,如何判-1?目测次数不会很多,直接暴力跑一千次,出不来就是-1;或者标记是否这个状态出现过,如果出现过那也能说明达不到,肯定是这个方法比较快
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <iomanip>
#include <climits>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
int a[MAXN];
int main(){
    #ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    string s1, s2, s;
    cin >> n;
    for(int i=1;i<=n;i++){
        cin >> m;
        cin >> s1 >> s2 >> s;
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        reverse(s.begin(), s.end());
        bool flag = false;
        int ans = 0;
        map<string, int> mp;
        while(true){
            string ss = "";
            for(int k=0;k<m;k++){
                ss += s1[k];
                ss += s2[k];
            }
            // cout << j << '\n';
            // cout << s1 << ' ' << s2 << '\n';
            // cout << ss << ' ' << s << '\n';
            ans += 1;
            if(ss == s){
                flag = true;
                break;
            }
            if(mp.count(ss)) break;
            mp[ss] = 1;
            if(m != 1){
                s1 = ss.substr(m);
                s2 = ss.substr(0, m);
            }else{
                swap(s1, s2);
            }
        }
        if(flag) cout << i << ' ' << ans << '\n';
        else cout << i << ' ' << -1 << '\n';
    }
    return 0;
}

8. FZU 2150 Fire Game

  • 题意是这样的,选择两个草坪开始烧,草坪可以选择同一个,且只能往周围四个位置传递影响,问最少需要多长时间把所有草坪烧完
  • 双起点 b f s bfs bfs,然后暴力
  • 这个题我提交不了,但是跟别人代码对拍感觉没什么问题,扫一眼看起来思路是一样的
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
char mp[12][12];
int vis[12][12];
int n, m;
struct Node{
    int x, y;
    int tim;
}s[200];
int tot;
int ans;
int now;
int xx[] = {-1, 1, 0, 0};
int yy[] = {0, 0, -1, 1};
void bfs(int x1, int y1, int x2, int y2){
    Node x;
    x.x = x1;
    x.y = y1;
    x.tim = 0;
    queue<Node> q;
    q.push(x);
    vis[x1][y1] = 1;
    x.x = x2;
    x.y = y2;
    x.tim = 0;
    if(!vis[x2][y2]) q.push(x);
    vis[x2][y2] = 1;
    now = 0;
    while(!q.empty()){
        x = q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx = x.x + xx[i];
            int dy = x.y + yy[i];
            if(dx < 1 || dy < 1 || dx > n || dy > m || mp[dx][dy] == '.' || vis[dx][dy] == 1) continue;
            vis[dx][dy] = 1;
            Node u;
            u.tim = x.tim + 1;
            u.x = dx;
            u.y = dy;
            q.push(u);
            now = max(now, u.tim);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(mp[i][j] == '#' && !vis[i][j]){
                return;
            }
        }
    }
    ans = min(ans, now);
}
int main(){
    #ifdef LOCAL
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    for(int _=1;_<=t;_++){
        cin >> n >> m;
        tot = 0;
        ans = INT_MAX;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                cin >> mp[i][j];
                if(mp[i][j] == '#'){
                    s[tot].x = i;
                    s[tot].y = j;
                    tot += 1;
                }
            }
        }
        for(int i=0;i<tot;i++){
            for(int j=i+1;j<tot;j++){
                memset(vis, 0, sizeof vis);
                bfs(s[i].x, s[i].y, s[j].x, s[j].y);
            }
        }
        for(int i=0;i<tot;i++){
            memset(vis, 0, sizeof vis);
            bfs(s[i].x, s[i].y, s[i].x, s[i].y);
        }
        cout << "Case " << _ << ": ";
        cout << (ans == INT_MAX ? -1 : ans) << '\n';
    }
    return 0;
}

10. UVA11264 Fire!

  • 模拟,用两个队列存一下
#include <bits/stdc++.h>

using namespace std;

struct st{
    int x, y, tim;
};
int xx[] = {1, 0, -1, 0};
int yy[] = {0, 1, 0, -1};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n, m;
        cin >> n >> m;
        vector<vector<char> > mp(n + 1, vector<char> (m + 1));
        vector<vector<int> > vv(n + 1, vector<int> (m + 1));
        vector<int> vis(10000);
        int a, b;
        vector<pair<int, int> > vs;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                cin >> mp[i][j];
                if(mp[i][j] == 'J'){
                    a = i;
                    b = j;
                }
                if(mp[i][j] == 'F'){
                    vs.push_back(make_pair(i, j));
                }
            }
        }
        function<int()> Bfs = [&](){
            queue<st> q;
            st now;
            q.push(st{a, b, 0});
            queue<st> fire;
            queue<st> q2;
            for(auto i : vs){
                fire.push(st{i.first, i.second, 0});
            }
            while(!q.empty()){
                auto u = q.front();
                q.pop();
                if(!vis[u.tim]){    
                    // for(int i=1;i<=n;i++){
                    //     for(int j=1;j<=m;j++){
                    //         cout << mp[i][j];
                    //     }cout << '\n';
                    // }
                    while(!fire.empty()){
                        auto top = fire.front();
                        fire.pop();
                        int dx = top.x;
                        int dy = top.y;
                        for(int i=0;i<4;i++){
                            int x = dx + xx[i];
                            int y = dy + yy[i];
                            if(x < 1 || y < 1 || x > n || y > m || mp[x][y] == '#' || mp[x][y] == 'F') continue;
                            // cout << x << ' ' << y << '\n';
                            mp[x][y] = 'F';
                            q2.push(st{x, y, 0});
                        }
                    }
                    fire = q2;
                    vis[u.tim] = 1;
                    while(!q2.empty()){
                        q2.pop();
                    }
                }
                for(int i=0;i<4;i++){
                    int dx = u.x + xx[i];
                    int dy = u.y + yy[i];
                    if(dx < 1 || dy < 1 || dx > n || dy > m){
                        return u.tim + 1;
                    }
                    if(mp[dx][dy] == '#' || vv[dx][dy] || mp[dx][dy] == 'F') continue;
                    vv[dx][dy] = 1;
                    now.x = dx;
                    now.y = dy;
                    now.tim = u.tim + 1;
                    q.push(now);
                }
            }
            return -1;
        };
        int ans = Bfs();
        if(ans == -1){
            cout << "IMPOSSIBLE" << '\n';
        }else cout << ans << '\n';
    }
    return 0;
}

11. poj3984 迷宫问题

  • 用数组记录路径,常规操作
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
int a[MAXN];
int mp[10][10];
int xx[] = {1, 0};
int yy[] = {0, 1};
struct st{
    int x, y;
    int tim;
    int ans_x[100];
    int ans_y[100];
};
void bfs(){
    st now;
    now.x = 1;
    now.y = 1;
    now.tim = 0;
    queue<st> q;
    now.ans_x[0] = 0;
    now.ans_y[0] = 0;
    q.push(now);
    while(!q.empty()){
        now = q.front();
        q.pop();
        for(int i=0;i<2;i++){
            int dx = now.x + xx[i];
            int dy = now.y + yy[i];
            if(dx < 1 || dy < 1 || dx > 5 || dy > 5 || mp[dx][dy] == 1) continue;
            st top = now;
            top.tim += 1;
            top.x = dx;
            top.y = dy;
            top.ans_x[top.tim] = dx - 1;
            top.ans_y[top.tim] = dy - 1;
            if(dx == 5 && dy == 5){
                for(int i=0;i<=now.tim;i++){
                    cout << '(' << now.ans_x[i] << ", " << now.ans_y[i] << ")\n";
                }
                cout << '(' << 4 << ", " << 4 << ")\n";
                return;
            }
            q.push(top);
        }
    }
}
int main(){
    #ifdef LOCAL
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    for(int i=1;i<=5;i++){
        for(int j=1;j<=5;j++){
            cin >> mp[i][j];
        }
    }
    bfs();
    return 0;
}

12. hdu 1241

  • 额,没什么好说的
#include <bits/stdc++.h>

using namespace std;

int xx[] = {1, 0, -1, 0, 1, 1, -1, -1};
int yy[] = {0, 1, 0, -1, 1, -1, -1, 1};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    while(cin >> n >> m){
        if(n == 0 && m == 0) break;
        vector<vector<char> > a(n + 1, vector<char> (m + 1));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                cin >> a[i][j];
            }
        }
        function<void(int, int)> Dfs = [&](int x, int y){
            for(int i=0;i<8;i++){
                int dx = x + xx[i];
                int dy = y + yy[i];
                if(dx < 1 || dy < 1 || dx > n || dy > m || a[dx][dy] == '*') continue;
                a[dx][dy] = '*';
                Dfs(dx, dy);
            }
        };
        int ans = 0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(a[i][j] == '@'){
                    ans += 1;
                    Dfs(i, j);
                }
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

13. hdu 1495 非常可乐

  • 搜索模拟六种可能的倒水方案,我写的比较麻烦可能,应该有不易错的写法,但是练习就要练最不会的东西
  • 似乎有数论解法,求 s , n , m s,n,m s,n,m g c d gcd gcd,然后都除掉最后看 s s s的奇偶,如果是偶数答案就是 s − 1 s-1 s1,虽然巧妙,但是想到或者算出来可能不太简单,如果赛场上遇到这样的问题搜索应该是比较靠谱的办法,如果打表找规律还不如写搜索
#include <bits/stdc++.h>

using namespace std;

struct st{
    int s, n, m, tim;
};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int s, n, m;
    while(cin >> s >> n >> m){
        if(s == 0 && n == 0 && m == 0) break;
        vector<vector<vector<int> > > book(s + 1, vector<vector<int> > (n + 1, vector<int> (m + 1)));
        function<int()> Bfs = [&](){
            queue<st> q;
            st now;
            q.push(st{s, 0, 0, 0});
            book[s][0][0] = 1;
            while(!q.empty()){
                auto u = q.front();
                q.pop();
                // queue<st> q2;
                // q2 = q;
                // while(!q2.empty()){
                //     auto v = q2.front();
                //     cout << v.s << ' ' << v.n << ' ' << v.m << ' ' << v.tim << '\n';
                //     q2.pop();
                // }
                // cout << '\n';
                if(u.m == s / 2 && (u.n == 0 || u.s == 0)){
                    // cout << u.m << ' ' << u.n << ' ' << u.s << '\n';
                    return u.tim;
                }
                if(u.n == s / 2 && (u.s == 0 || u.m == 0)){
                    return u.tim;
                }
                if(u.s == s / 2 && (u.n == 0 || u.m == 0)){
                    return u.tim;
                }
                now.tim = u.tim + 1;
                if(u.s > 0){
                    if(u.n < n){
                        int res = n - u.n;
                        if(res > u.s){
                            now.s = 0;
                            now.n = u.n + u.s;
                            now.m = u.m;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }else if(res > 0){
                            now.s = u.s - res;
                            now.n = n;
                            now.m = u.m;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }
                    }
                    if(u.m < m){
                        int res = m - u.m;
                        if(res > u.s){
                            now.s = 0;
                            now.n = u.n;
                            now.m = u.m + u.s;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }else if(res > 0){
                            now.s = u.s - res;
                            now.n = u.n;
                            now.m = m;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }
                    }
                }
                if(u.n > 0){
                    if(u.s < s){
                        int res = s - u.s;
                        if(res > u.n){
                            now.n = 0;
                            now.s = u.s + u.n;
                            now.m = u.m;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }else if(res > 0){
                            now.s = s;
                            now.n = u.n - res;
                            now.m = u.m;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }
                    }
                    if(u.m < m){
                        int res = m - u.m;
                        if(res > u.n){
                            now.n = 0;
                            now.s = u.s;
                            now.m = u.m + u.n;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }else if(res > 0){
                            now.n = u.n - res;
                            now.m = m;
                            now.s = u.s;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }
                    }
                }
                if(u.m > 0){
                    if(u.s < s){
                        int res = s - u.s;
                        if(res > u.m){
                            now.m = 0;
                            now.n = u.n;
                            now.s = u.s + u.m;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }else if(res > 0){
                            now.s = s;
                            now.n = u.n;
                            now.m = u.m - res;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }
                    }
                    if(u.n < n){
                        int res = n - u.n;
                        if(res > u.m){
                            now.m = 0;
                            now.s = u.s;
                            now.n = u.n + u.m;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }else if(res > 0){
                            now.m = u.m - res;
                            now.n = n;
                            now.s = u.s;
                            if(!book[now.s][now.n][now.m]){
                                q.push(now);
                                book[now.s][now.n][now.m] = 1;
                            }
                        }
                    }
                }
            }
            return -1;
        };
        if(s & 1) cout << "NO" << '\n';
        else{
            int ans = Bfs();
            if(ans != -1) cout << ans << '\n';
            else cout << "NO" << '\n';
        } 
    }
    return 0;
}

14. hdu 2612 Find a way

  • 记录一下KFC的位置,跑两次bfs找到每个人到KFC的距离,遍历每一个KFC取最小值即可
#include <bits/stdc++.h>

using namespace std;

struct st{
    int x, y;
    int tim;
};
int xx[] = {1, 0, -1, 0};
int yy[] = {0, 1, 0, -1};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    while(cin >> n >> m){
        vector<vector<char> > a(n + 1, vector<char> (m + 1));
        int x1, y1, x2, y2;
        vector<pair<int, int> > at;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                cin >> a[i][j];
                if(a[i][j] == 'Y'){
                    x1 = i;
                    y1 = j;
                }
                if(a[i][j] == 'M'){
                    x2 = i;
                    y2 = j;
                }
                if(a[i][j] == '@'){
                    at.push_back(make_pair(i, j));
                }
            }
        }
        int ans = INT_MAX;
        vector<vector<int> > vis1(n + 1, vector<int> (m + 1));
        vector<vector<int> > vis2(n + 1, vector<int> (m + 1));
        vector<vector<int> > dis1(n + 1, vector<int> (m + 1, INT_MAX));
        vector<vector<int> > dis2(n + 1, vector<int> (m + 1, INT_MAX));
        function<void(vector<vector<int> > &, vector<vector<int> > &, int, int)> Bfs = [&](vector<vector<int> > &vis, vector<vector<int> > &dis, int x0, int y0){
            queue<st> q;
            st x, now;
            x.x = x0;
            x.y = y0;
            x.tim = 0;
            q.push(x);
            while(!q.empty()){
                x = q.front();
                q.pop();
                for(int i=0;i<4;i++){
                    int dx = x.x + xx[i];
                    int dy = x.y + yy[i];
                    if(dx < 1 || dy < 1 || dx > n || dy > m || a[dx][dy] == '#' || vis[dx][dy]) continue;
                    vis[dx][dy] = 1;
                    now.x = dx;
                    now.y = dy;
                    now.tim = x.tim + 11;
                    if(a[dx][dy] == '@'){
                        dis[dx][dy] = now.tim;   
                    }
                    q.push(now);
                }
            }
        };
        Bfs(vis1, dis1, x1, y1);
        Bfs(vis2, dis2, x2, y2);
        for(auto i : at){
            if(dis1[i.first][i.second] != INT_MAX && dis2[i.first][i.second] != INT_MAX)
                ans = min(ans, dis1[i.first][i.second] + dis2[i.first][i.second]);
        }
        cout << ans << '\n';
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clarence Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值