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

来源:互联网 发布:手机淘宝如何复制链接 编辑:程序博客网 时间:2024/04/29 22:10

再简单说明一下题意,规定一开始按钮状态为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;}


0 0
原创粉丝点击