• c++最小步数模型(魔板)


    C++ 最小步数模型通常用于寻找两个点之间的最短路径或最少步数。以下是一个基本的 C++ 最小步数模型的示例代码:

    1. #include
    2. using namespace std;
    3. const int N = 1e5 + 5;
    4. vector<int> G[N];
    5. int d[N];
    6. bool vis[N];
    7. void bfs(int s) {
    8. queue<int> que;
    9. que.push(s);
    10. vis[s] = true;
    11. while (!que.empty()) {
    12. int x = que.front();
    13. que.pop();
    14. for (auto y : G[x]) {
    15. if (!vis[y]) {
    16. que.push(y);
    17. vis[y] = true;
    18. d[y] = d[x] + 1;
    19. }
    20. }
    21. }
    22. }
    23. int main() {
    24. int n, m;
    25. cin >> n >> m;
    26. for (int i = 1; i <= m; i++) {
    27. int x, y;
    28. cin >> x >> y;
    29. G[x].push_back(y);
    30. G[y].push_back(x);
    31. }
    32. bfs(1);
    33. cout << d[n] << endl;
    34. return 0;
    35. }

    在这个例子中,我们使用了广度优先搜索算法(BFS)来遍历整个图,并计算每个点到起点的最短距离。具体地,我们将起点加入队列中,并在之后的每个循环中依次访问队列中的每个点。对于每个访问过的点,我们遍历与其相邻的所有节点,并在遇到未访问过的节点时将其加入队列,并更新其距离,即 d[y] = d[x] + 1。最后,我们输出终点 n 到起点的最短距离 d[n]

    注意,我们还需要使用一个数组 vis 来记录每个节点是否已经被访问过。在每次遍历时,我们需要先检查当前节点是否已经被访问过,如果访问过则跳过,否则将其标记为已访问,并处理其相邻节点。

    先看题目:

    Rubik 先生在发明了风靡全球的魔方之后,又发明了它的二维版本——魔板。

    这是一张有 8 个大小相同的格子的魔板:

    1 2 3 4
    8 7 6 5
    我们知道魔板的每一个方格都有一种颜色。

    这 8 种颜色用前 8 个正整数来表示。

    可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。

    对于上图的魔板状态,我们用序列 (1,2,3,4,5,6,7,8)来表示,这是基本状态。

    这里提供三种基本操作,分别用大写字母 A,B,C 来表示(可以通过这些操作改变魔板的状态):

    A:交换上下两行;
    B:将最右边的一列插入到最左边;
    C:魔板中央对的4个数作顺时针旋转。

    下面是对基本状态进行操作的示范:

    A:

    1. 8 7 6 5
    2. 1 2 3 4

    B:

    1. 4 1 2 3
    2. 5 8 7 6

    C:

    1. 1 7 2 4
    2. 8 6 3 5

    对于每种可能的状态,这三种基本操作都可以使用。

    你要编程计算用最少的基本操作完成基本状态到特殊状态的转换,输出基本操作序列。

    注意:数据保证一定有解。

    输入格式

    输入仅一行,包括 88 个整数,用空格分开,表示目标状态。

    输出格式

    输出文件的第一行包括一个整数,表示最短操作序列的长度。

    如果操作序列的长度大于0,则在第二行输出字典序最小的操作序列。

    数据范围

    输入数据中的所有数字均为 11 到 88 之间的整数。

    输入样例:
    2 6 8 4 5 7 3 1

    输出样例:

    1. 7
    2. BCABCCB

    先看代码

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. unordered_mapchar>> pre; // pre存的是当前状态所对应的上一状态的状态和操作
    8. inline string operA(string str)
    9. {
    10. for (int i = 0; i < 4; ++ i) swap(str[i], str[7 - i]);
    11. return str;
    12. }
    13. inline string operB(string str)
    14. {
    15. for (int i = 0; i < 3; ++ i) swap(str[2 - i], str[3 - i]), swap(str[4 + i], str[5 + i]);
    16. return str;
    17. }
    18. inline string operC(string str)
    19. {
    20. swap(str[1], str[2]), swap(str[5], str[6]), swap(str[1], str[5]);
    21. return str;
    22. }
    23. void bfs(string start, string end)
    24. {
    25. queue que;
    26. que.push(start); // 必须从start向end搜索才能保证字典序最小
    27. while (!que.empty())
    28. {
    29. string str = que.front();
    30. que.pop();
    31. if (str == end) return;
    32. string move[3]; // 记录下该状态可由三种操作所达到的新状态
    33. move[0] = operA(str), move[1] = operB(str), move[2] = operC(str);
    34. for (int i = 0; i < 3; ++ i) // 遍历三种状态
    35. {
    36. if (!pre.count(move[i])) // 如果当前状态还没有被记录过
    37. {
    38. que.push(move[i]); // 将当前状态入队
    39. pre[move[i]] = make_pair(str, 'A' + i); // 存下当前状态所对应的上一状态的状态和操作
    40. }
    41. }
    42. }
    43. }
    44. signed main()
    45. {
    46. int x;
    47. string start = "12345678", end, res;
    48. for (int i = 0; i < 8; ++ i)
    49. {
    50. scanf("%d", &x);
    51. end += char(x + '0');
    52. }
    53. bfs(start, end);
    54. while (end != start)
    55. { // 从最终状态向起始状态回溯
    56. res = pre[end].second + res; // 注意要把前一个操作放在输出序的前面
    57. end = pre[end].first;
    58. }
    59. if (res.length() == 0) printf("0");
    60. else printf("%d\n%s", res.length(), res.c_str());
    61. return 0;
    62. }
  • 相关阅读:
    DistributedDataParallel数据不均衡
    【Mysql】 InnoDB引擎深入- 二级索引、联合索引、回表、索引覆盖
    uniapp 去掉默认导航栏
    转铁蛋白偶联糖(单糖/多糖),(Transferrin)TF-PEG-Dextran葡聚糖/Lysozyme溶菌酶
    《学习强国》投稿发稿全攻略:三种方式助你实现投稿梦想!
    基于结构应力方法的焊接结构疲劳评估及实例分析(下篇)
    学生HTML个人网页作业作品:基于HTML实现教育培训机构网站模板毕业源码(8页)
    每日五道java面试题之spring篇(五)
    C语言:详细介绍了六种进程间通讯方式(还有一种socket在主页关于socket的介绍里面有详细介绍,欢迎观看)
    Linux基础 - 服务管理(systemd)
  • 原文地址:https://blog.csdn.net/2301_76180325/article/details/133283005