長安大學新生賽 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;


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章