• 长安大学新生赛 H题 拉面女神的魔盒


    再简单说明一下题意,规定一开始按钮状态为0 0 0 0 0 0,输入终点状态,求最少的操作步数,对于每个按钮,有以下规定:

    按钮①:可以任意想顺时针或者逆时针旋转,一次转动一格

    按钮②:当6个旋钮的数字中奇数偶数个数为相同时才能转动,向顺时针或者逆时针转动一格

    按钮③:只能向逆时针方向转动,一次转动7格。

    按钮④:只能向逆时针方向转动,一次转动(sum % 9 + 1)格,sum为当前六个数之和

    按钮⑤:当①③⑤这三个旋钮数字之和正好为9的时候才能转动,顺时针或者逆时针旋转一格

    按钮⑥:当按钮②的数字为0的时候才能转动,只能向顺时针转动,一次转动三格。


    这个题一开始反应的是能否直接用DFS并判重来做。。然而明显不可以。

    后来发现其实这肯定是个BFS的题目,进而根据题目知道终点,知道起点这个特性,想到可以用A*或者双向BFS来做,但是不知道怎么列启发式函数,所以就用双向BFS来做吧。代码很长,因为正向和反向不完全一样的判断条件,比较坑。。。未提交过,可能有错误,欢迎指正。

    代码如下:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <map>
    #include <vector>
    #include <cmath>
    #include <iomanip>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    struct VIS{
        int flag;
        int step;
    }vis[1000001];
    
    int dis[2] = {1, -1};
    
    struct num{
        int n[6];
        int step;
        friend bool operator <(num a, num b)
        {
            return a.step < b.step;
        }
    };
    
    int ans[6];
    int init[6];
    
    bool judge(num a){
        for(int i = 0; i < 6; i ++)
            if(a.n[i] != ans[i]);
                return false;
        return true;
    }
    
    int total(num a){
        int i, sum;
        sum = 0;
        for(i = 0; i < 6; i ++)
            sum = sum * 10 + a.n[i];
        return sum;
    }
    
    int bfs(void){
        memset(vis, 0, sizeof(vis));
        queue<num> q;
        queue<num> p;
        num pre, lst;
        int i, t,  sp = 0;
        long sum;
    
        for(i = 0; i < 6; i ++)
            pre.n[i] = init[i];
        sum = total(pre);
        vis[sum].flag = 1;
        vis[sum].step = 0;
        pre.step = 0;
        q.push(pre);
    
        for(i = 0; i < 6; i ++)
            lst.n[i] = ans[i];
        sum = total(lst);
        vis[sum].flag = 2;
        vis[sum].step = 0;
        lst.step = 0;
        p.push(lst);
    
        while(!q.empty() && !p.empty()){
            while(q.front().step == sp){
                pre = q.front();
                q.pop();
                for(i = 0; i < 6; i ++){
                    if(i == 0){
                        for(t = 0; t < 2; t ++){
                            lst = pre;
                            lst.n[0] = pre.n[0] + dis[t];
                            if(lst.n[i] < 0)
                                lst.n[i] += 10;
                            else if(lst.n[i] >= 10)
                                lst.n[i] -= 10;
                            sum = total(lst);
                            lst.step = pre.step + 1;
                            if(vis[sum].flag == 1)
                                continue;
                            if(vis[sum].flag == 2)
                                return lst.step + vis[sum].step;
                            vis[sum].flag = 1;
                            vis[sum].step = lst.step;
                            q.push(lst);
                        }
                    }
                    else if(i == 1){
                        int temp = 0;
                        for(int j = 0; j < 6; j ++){
                            if(pre.n[j] % 2)
                                temp ++;
                            else
                                temp --;
                        }
                        if(temp != 0)
                            continue;
                        for(t = 0; t < 2; t ++){
                            lst = pre;
                            lst.n[1] = pre.n[1] + dis[t];
                            if(lst.n[i] < 0)
                                lst.n[i] += 10;
                            else if(lst.n[i] >= 10)
                                lst.n[i] -= 10;
                            sum = total(lst);
                            lst.step = pre.step + 1;
                            if(vis[sum].flag == 1)
                                continue;
                            if(vis[sum].flag == 2)
                                return lst.step + vis[sum].step;
                            vis[sum].flag = 1;
                            vis[sum].step = lst.step;
                            q.push(lst);
                        }
                    }
                    else if(i == 2){
                        lst = pre;
                        lst.n[2] = pre.n[2] + 7;
                        if(lst.n[i] < 0)
                            lst.n[i] += 10;
                        else if(lst.n[i] >= 10)
                            lst.n[i] -= 10;
                        sum = total(lst);
                        lst. step = pre.step + 1;
                        if(vis[sum].flag == 1)
                            continue;
                        if(vis[sum].flag == 2)
                            return lst.step + vis[sum].step;
                        vis[sum].flag = 1;
                        vis[sum].step = lst.step;
                        q.push(lst);
                    }
                    else if(i == 3){
                        lst = pre;
                        int temp = 0;
                        for(int j = 0; j < 6; j ++){
                            temp += lst.n[j];
                        }
                        temp = temp % 9 + 1;
                        lst.n[3] = pre.n[3] + temp;
                        if(lst.n[i] < 0)
                            lst.n[i] += 10;
                        else if(lst.n[i] >= 10)
                            lst.n[i] -= 10;
                        sum = total(lst);
                        lst. step = pre.step + 1;
                        if(vis[sum].flag == 1)
                            continue;
                        if(vis[sum].flag == 2)
                            return lst.step + vis[sum].step;
                        vis[sum].flag = 1;
                        vis[sum].step = lst.step;
                        q.push(lst);
                    }
                    else if(i == 4 && (pre.n[0] + pre.n[2] + pre.n[4] == 9)){
                        for(t = 0; t < 2; t ++){
                            lst = pre;
                            lst.n[4] = pre.n[4] + dis[t];
                            if(lst.n[i] < 0)
                                lst.n[i] += 10;
                            else if(lst.n[i] >= 10)
                                lst.n[i] -= 10;
                            sum = total(lst);
                            lst.step = pre.step + 1;
                            if(vis[sum].flag == 1)
                                continue;
                            if(vis[sum].flag == 2)
                                return lst.step + vis[sum].step;
                            vis[sum].flag = 1;
                            vis[sum].step = lst.step;
                            q.push(lst);
                        }
                    }
                    else if(i == 5 && pre.n[1] == 0){
                        lst = pre;
                        lst.n[5] = pre.n[5] - 3;
                        if(lst.n[i] < 0)
                            lst.n[i] += 10;
                        else if(lst.n[i] >= 10)
                            lst.n[i] -= 10;
                        sum = total(lst);
                        lst. step = pre.step + 1;
                        if(vis[sum].flag == 1)
                            continue;
                        if(vis[sum].flag == 2)
                            return lst.step + vis[sum].step;
                        vis[sum].flag = 1;
                        vis[sum].step = lst.step;
                        q.push(lst);
                    }
                }
            }
    
    
            while(p.front().step == sp){
                pre = p.front();
                p.pop();
    
                for(i = 0; i < 6; i ++){
                    if(i == 0){
                        for(t = 0; t < 2; t ++){
                            lst = pre;
                            lst.n[0] = pre.n[0] + dis[t];
                            if(lst.n[i] < 0)
                                lst.n[i] += 10;
                            else if(lst.n[i] >= 10)
                                lst.n[i] -= 10;
                            sum = total(lst);
                            lst.step = pre.step + 1;
                            if(vis[sum].flag == 2)
                                continue;
                            if(vis[sum].flag == 1)
                                return lst.step + vis[sum].step;
                            vis[sum].flag = 2;
                            vis[sum].step = lst.step;
                            p.push(lst);
                        }
                    }
                    else if(i == 1){
                        for(t = 0; t < 2; t ++){
                            lst = pre;
                            lst.n[1] = pre.n[1] + dis[t];
                            if(lst.n[i] < 0)
                                lst.n[i] += 10;
                            else if(lst.n[i] >= 10)
                                lst.n[i] -= 10;
                            int temp = 0;
                            for(int j = 0; j < 6; j ++)
                                if(lst.n[j] % 2)
                                    temp ++;
                                else
                                    temp --;
                            if(temp != 0)
                                continue;
                            sum = total(lst);
                            lst.step = pre.step + 1;
                            if(vis[sum].flag == 2)
                                continue;
                            if(vis[sum].flag == 1)
                                return lst.step + vis[sum].step;
                            vis[sum].flag = 2;
                            vis[sum].step = lst.step;
                            p.push(lst);
                        }
                    }
                    else if(i == 2){
                        lst = pre;
                        lst.n[2] = pre.n[2] - 7;
                        if(lst.n[i] < 0)
                            lst.n[i] += 10;
                        else if(lst.n[i] >= 10)
                            lst.n[i] -= 10;
                        sum = total(lst);
                        lst. step = pre.step + 1;
                        if(vis[sum].flag == 2)
                            continue;
                        if(vis[sum].flag == 1)
                            return lst.step + vis[sum].step;
                        vis[sum].flag = 2;
                        vis[sum].step = lst.step;
                        p.push(lst);
                    }
                    else if(i == 3){
                        for(t = 0; t < 10; t ++){
                            lst.n[3] = pre.n[3] - t;
                            if(lst.n[i] < 0)
                                lst.n[i] += 10;
                            else if(lst.n[i] >= 10)
                                lst.n[i] -= 10;
                            int temp = 0;
                            for(int j = 0; j < 6; j ++){
                                temp += lst.n[j];
                            }
                            if(temp % 9 + 1 != i)
                                continue;
                            sum = total(lst);
                            lst.step = pre.step + 1;
                            if(vis[sum].flag == 2)
                                continue;
                            if(vis[sum].flag == 1)
                                return lst.step + vis[sum].step;
                            vis[sum].flag = 2;
                            vis[sum].step = lst.step;
                            p.push(lst);
                        }
                    }
                    else if(i == 4){
                        for(t = 0; t < 2; t ++){
                            lst = pre;
                            lst.n[4] = pre.n[4] + dis[t];
                            if(lst.n[i] < 0)
                                lst.n[i] += 10;
                            else if(lst.n[i] >= 10)
                                lst.n[i] -= 10;
                            if(lst.n[0] + lst.n[2] + lst.n[4] != 9)
                                continue;
                            sum = total(lst);
                            lst.step = pre.step + 1;
                            if(vis[sum].flag == 2)
                                continue;
                            if(vis[sum].flag == 1)
                                return lst.step + vis[sum].step;
                            vis[sum].flag = 2;
                            vis[sum].step = lst.step;
                            p.push(lst);
                        }
                    }
                    else if(i == 5 && pre.n[1] == 0){
                        lst = pre;
                        lst.n[5] = pre.n[5] + 3;
                        if(lst.n[i] < 0)
                            lst.n[i] += 10;
                        else if(lst.n[i] >= 10)
                            lst.n[i] -= 10;
                        sum = total(lst);
                        lst.step = pre.step + 1;
                        if(vis[sum].flag == 2)
                            continue;
                        if(vis[sum].flag == 1)
                            return lst.step + vis[sum].step;
                        vis[sum].flag = 2;
                        vis[sum].step = lst.step;
                        p.push(lst);
                    }
                }
            }
    
            ++ sp;
        }
        return -1;
    }
    
    int T;
    
    
    int main(void){
    
        char c;
        //freopen("out.txt", "r", stdin);
        //freopen("in.txt", "w",stdout);
        cin >> T;
        while(T --){
            bool flag = false;
            for(int i = 0; i < 6; i ++){
                cin >> ans[i];
                init[i] = 0;
                if(ans[i])
                    flag = true;
            }
            if(!flag)
                cout << "0" << endl;
            int res = bfs();
            cout << res << endl;
        }
        return 0;
    
    
    }
    


  • 相关阅读:
    MVC HtmlHelper
    Bellman-ford算法、SPFA算法求解最短路模板
    Dijkstra算法求最短路模板
    静态邻接表模板
    HDU 4511 小明系列故事——女友的考验 ( Trie图 && DP )
    HDU 4758 Walk Through Squares ( Trie图 && 状压DP && 数量限制类型 )
    HDU 3341 Lost's revenge ( Trie图 && 状压DP && 数量限制类型 )
    POJ 3691 DNA repair ( Trie图 && DP )
    POJ 2456 Aggressive cows ( 二分 && 贪心 )
    HDU 2296 Ring ( Trie图 && DP && DP状态记录)
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136043.html
Copyright © 2020-2023  润新知