Acwing-----算法提高课第二章搜索(三)

190. 字串变换

#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <queue>

using namespace std;

const int N = 6;

int n;
string a[N], b[N];

int extend(queue<string>& q, unordered_map<string, int>& da, unordered_map<string, int>& db, string a[], string b[]) {
    for (int k = 0, sk = q.size(); k < sk; k ++ ) {
        string t = q.front();
        q.pop();

        for (int i = 0; i < t.size(); i ++ ) {
            for (int j = 0; j < n; j ++ ) {
                if (t.substr(i, a[j].size()) == a[j]) {
                    string state = t.substr(0, i) + b[j] + t.substr(i + a[j].size());
                    if (da.count(state)) continue;
                    if (db.count(state)) return da[t] + 1 + db[state];
                    da[state] = da[t] + 1;
                    q.push(state);
                }
            }
        }
    }

    return 11;
}

int bfs(string A, string B) {
    queue<string> qa, qb;
    unordered_map<string, int> da, db;
    qa.push(A), da[A] = 0;
    qb.push(B), db[B] = 0;

    while (qa.size() && qb.size()) {
        int t;
        if (qa.size() <= qb.size()) t = extend(qa, da, db, a, b);
        else t= extend(qb, db, da, b, a);

        if (t <= 10) return t;
    }

    return 11;
}

int main() {
    string A, B;
    cin >> A >> B;
    while (cin >> a[n] >> b[n]) n ++ ;

    int step = bfs(A, B);
    if (step > 10) puts("NO ANSWER!");
    else printf("%d\n", step);

    return 0;
}

179. 八数码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;

int f(string state) {
    int ans = 0;
    for (int i = 0; i < state.size(); ++i) {
        if (state[i] != 'x') {
            int t = state[i] - '1';
            ans += abs(i / 3 - t / 3) + abs(i % 3 - t % 3);
        }
    }
    return ans;
}

string bfs(string start) {
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    char op[4] = {'u', 'r', 'd', 'l'};
    
    string end = "12345678x";
    unordered_map<string, int> dist;
    unordered_map<string, pair<string, char>> prev;
    priority_queue<pair<int, string>, vector<pair<int, string>>, greater<pair<int, string>>> heap;

    heap.push({f(start), start});
    dist[start] = 0;
    
    while (heap.size()) {
        auto t= heap.top();
        heap.pop();
        
        string state = t.second;
        if (state == end) break;
        
        int step = dist[state];
        int x, y;
        for (int i = 0; i < state.size(); ++i) {
            if (state[i] == 'x') {
                x = i / 3, y = i % 3;
                break;
            }
        }
        string source = state;
        for (int i = 0; i < 4; ++i) {
            int a = x + dx[i], b = y + dy[i];
            if (a >= 0 && a < 3 && b >= 0 && b < 3) {
                swap(state[x * 3 + y], state[a * 3 + b]);
                if (!dist.count(state) || dist[state] > step + 1) {
                    dist[state] = step + 1;
                    prev[state] = {source, op[i]};
                    heap.push({dist[state] + f(state), state});
                }
                swap(state[x * 3 + y], state[a * 3 + b]);
            }
        }
    }
    string ans;
    while (start != end) {
        ans += prev[end].second;
        end = prev[end].first;
    }
    reverse(ans.begin(), ans.end());
    return ans;
}

int main() {
    string g, c, seq;
    while (cin >> c) {
        g += c;
        if (c != "x") seq += c;
    }
    
    int t = 0;
    for (int i = 0; i < seq.size(); ++i) {
        for (int j = i + 1; j < seq.size(); ++j) {
            if (seq[i] > seq[j]) ++t;
        }
    }
    
    if (t % 2) cout << "unsolvable" << endl;
    else cout << bfs(g) << endl;
    return 0;
}

178. 第K短路

#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;
typedef pair<int, int> PII;
typedef pair<int, PII> PIII;
#define x first
#define y second
const int N = 1010, M = 200010;

int n, m, S, T, K;
int h[N], rh[N], e[M], w[M], ne[M], idx, dist[N], cnt[N];
bool st[N];

void add(int h[], int a, int b, int c) {
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

void dijkstra() {
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, T});
    
    memset(dist, 0x3f, sizeof dist);
    dist[T] = 0;
    
    while (heap.size()) {
        auto t = heap.top();
        heap.pop();
        
        int ver = t.y;
        if (st[ver]) continue;
        st[ver] = true;
        
        for (int i = rh[ver]; ~i; i = ne[i]) {
            int j = e[i];
            if (dist[j] > dist[ver] + w[i]) {
                dist[j] = dist[ver] + w[i];
                heap.push({dist[j], j});
            }
        }
    }
}

int astar() {
    priority_queue<PIII, vector<PIII>, greater<PIII>> heap;
    heap.push({dist[S], {0, S}});
    
    while (heap.size()) {
        auto t = heap.top();
        heap.pop();
        
        int ver = t.y.y, distance = t.y.x;
        cnt[ver]++;
        if (cnt[T] == K) return distance;
        
        for (int i = h[ver]; ~i; i = ne[i]) {
            int j = e[i];
            if (cnt[j] < K)
                heap.push({distance + w[i] + dist[j], {distance + w[i], j}});
        }
    }
    return -1;
}

int main() {
    cin >> n >> m;
    memset(h, -1, sizeof h);
    memset(rh, -1, sizeof rh);
    
    for (int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        add(h, a, b, c);
        add(rh, b, a, c);
    }
    
    cin >> S >> T >> K;
    if (S == T) K++;
    
    dijkstra();
    cout << astar() << endl;
    return 0;
}
posted @ 2020-09-26 22:21  景云ⁿ  阅读(156)  评论(0编辑  收藏  举报