栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

zoj 3020 Puzzle Quest

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

zoj 3020 Puzzle Quest

#include <cstdio>#include <vector>#include <ext/hash_set>using namespace std;using namespace __gnu_cxx;class Puzzle{private:    friend class __puzzle_state;    const static int MAXN = 8;    class __puzzle_state    {        friend class Puzzle;        friend class __puzzle_state_hash;    private:        static int n;        int a[MAXN];    public:        class __puzzle_state_hash        {        public: size_t operator()(const __puzzle_state& s) const;        };        bool operator==(const __puzzle_state& s) const;    };    class __puzzle_solved    {    };public:    typedef __puzzle_state State;    typedef State::__puzzle_state_hash HashFunction;    typedef __puzzle_solved Solved;    const int n, m;private:    static const char* dir[4];    static State END;    hash_set<State, HashFunction> hs;    State vs[MAXN * MAXN];    char s[MAXN * MAXN][MAXN][MAXN];    pair<pair<int, int>, int> ins[MAXN * MAXN];    Puzzle(int n, int m);    Puzzle(const Puzzle& p);    void dfs(int l);    bool isvalid(char buf[MAXN][MAXN], int x, int y, char ch);    bool isvalid(char buf[MAXN][MAXN], int x1, int y1, int x2, int y2);    State toState(char buf[MAXN][MAXN]);public:    static bool run();};size_t Puzzle::HashFunction::operator()(const State& s) const{    size_t ret = 0;    for (int i = 0; i < State::n; i++) {        ret ^= (s.a[i] << i);    }    return ret;}int Puzzle::State::n;bool Puzzle::State::operator==(const State& s) const{    for (int i = 0; i < n; i++) {        if (a[i] != s.a[i]) { return false;        }    }    return true;}const char* Puzzle::dir[4] = {"left", "up", "right", "down"};Puzzle::State Puzzle::END;Puzzle::Puzzle(int n, int m)    : n(n), m(m){}void Puzzle::dfs(int l){    if (vs[l].a[0] < 0 || hs.count(vs[l]) > 0) {        return;    }    else if (vs[l] == END) {        printf("%dn", l);        for (int i = 0; i < l; i++) { printf("%d %d %sn", ins[i].first.first, ins[i].first.second, dir[ins[i].second]);        }        putchar('n');          throw Solved();    }    hs.insert(vs[l]);    for (int i = 0; i < n; i++) {        for (int j = 0; j < m; j++) { if (j > 0 && isvalid(s[l], i, j, i, j - 1)) {     for (int ii = 0; ii < n; ii++) {         for (int jj = 0; jj < m; jj++) {  s[l + 1][ii][jj] = s[l][ii][jj];         }     }     swap(s[l + 1][i][j], s[l + 1][i][j - 1]);     vs[l + 1] = toState(s[l + 1]);     ins[l] = make_pair(make_pair(i, j), 0);     dfs(l + 1); } if (i > 0 && isvalid(s[l], i, j, i - 1, j)) {     for (int ii = 0; ii < n; ii++) {         for (int jj = 0; jj < m; jj++) {  s[l + 1][ii][jj] = s[l][ii][jj];         }     }     swap(s[l + 1][i][j], s[l + 1][i - 1][j]);     vs[l + 1] = toState(s[l + 1]);     ins[l] = make_pair(make_pair(i, j), 1);     dfs(l + 1); }        }    }}bool Puzzle::isvalid(char buf[MAXN][MAXN], int x, int y, char ch){    if (x >= 2 && buf[x - 1][y] == ch && buf[x - 2][y] == ch) return true;    if (x < n - 2 && buf[x + 1][y] == ch && buf[x + 2][y] == ch) return true;    if (y >= 2 && buf[x][y - 1] == ch && buf[x][y - 2] == ch) return true;    if (y < m - 2 && buf[x][y + 1] == ch && buf[x][y + 2] == ch) return true;    if (x >= 1 && x < n - 1 && buf[x - 1][y] == ch && buf[x + 1][y] == ch) return true;    if (y >= 1 && y < m - 1 && buf[x][y - 1] == ch && buf[x][y + 1] == ch) return true;    return false;}bool Puzzle::isvalid(char buf[MAXN][MAXN], int x1, int y1, int x2, int y2){    char ch;    if (buf[x1][y1] != 0) {        ch = buf[x1][y1];        buf[x1][y1] = buf[x2][y2];        if (isvalid(buf, x2, y2, ch)) { buf[x1][y1] = ch; return true;        }        buf[x1][y1] = ch;    }    if (buf[x2][y2] != 0 && isvalid(buf, x1, y1, buf[x2][y2]) ) {        ch = buf[x2][y2];        buf[x2][y2] = buf[x1][y1];        if (isvalid(buf, x1, y1, ch)) { buf[x2][y2] = ch; return true;        }        buf[x2][y2] = ch;    }    return false;}Puzzle::State Puzzle::toState(char buf[MAXN][MAXN]){    static int cnt[8];    State ret;    int k;    bool flag = true, loop = true;    do {        loop = false;        for (int i = 0; i < n; i++) { k = 0; while (k < m - 2) {     if (buf[i][k] != 0 && abs(buf[i][k + 1]) == abs(buf[i][k]) && abs(buf[i][k + 2]) == abs(buf[i][k])) {         buf[i][k] = -abs(buf[i][k]);         while (++k < m && abs(buf[i][k]) == -buf[i][k - 1]) {  buf[i][k] = buf[i][k - 1];         }         loop = true;     }     else {         ++k;     } }        }        for (int j = 0; j < m; j++) { k = 0; while (k < n - 2) {     if (buf[k][j] != 0 && abs(buf[k + 1][j]) == abs(buf[k][j]) && abs(buf[k + 2][j]) == abs(buf[k][j])) {         buf[k][j] = -abs(buf[k][j]);         while (++k < n && abs(buf[k][j]) == -buf[k - 1][j]) {  buf[k][j] = buf[k - 1][j];         }         loop = true;     }     else {         ++k;     } }        }        if (!loop) { break;        }        for (int i = 1; i < 8; i++) { cnt[i] = 0;        }        for (int j = 0; j < m; j++) { k = n - 1; for (int i = n - 1; i >= 0; i--) {     if (buf[i][j] <= 0) {         continue;     }     buf[k--][j] = buf[i][j];     ++cnt[buf[i][j]]; } while (k >= 0) {     buf[k--][j] = 0; }        }        for (int i = 1; i < 8; i++) { if (cnt[i] > 0 && cnt[i] < 3) {     flag = false;     break; }        }    } while (flag);    if (!flag) {        ret.a[0] = -1;    }    else {        for (int i = 0; i < n; i++) { ret.a[i] = 0; for (int j = 0; j < m; j++) {     ret.a[i] ^= (buf[i][j] << 3 * j); }        }    }    return ret;}bool Puzzle::run(){    int n, m;    if (scanf("%d%d", &n, &m) == EOF) {        return false;    }    Puzzle p(n, m);    char ch;    State::n = n;    for (int i = 0; i < State::n; i++) {        END.a[i] = 0;    }    for (int i = 0; i < n; i++) {        for (int j = 0; j < m; j++) { while((ch = getchar()) == 'n'); switch (ch) {     case ' ': p.s[0][i][j] = 0; break;     case 'B': p.s[0][i][j] = 1; break;     case 'G': p.s[0][i][j] = 2; break;     case 'R': p.s[0][i][j] = 3; break;     case 'Y': p.s[0][i][j] = 4; break;     case 'O': p.s[0][i][j] = 5; break;     case 'P': p.s[0][i][j] = 6; break;     case 'M': p.s[0][i][j] = 7; break; }        }    }    p.vs[0] = p.toState(p.s[0]);    try {        p.dfs(0);    }    catch(Solved& sig) {    }    return true;}int main(){    while (Puzzle::run());    return 0;}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/379602.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号