The Rotation Game UVA - 1343

本文介绍了一道关于特殊棋盘布局的问题,利用迭代加深搜索策略解决如何以最少步骤使棋盘中心区域的数字统一,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目传送门

题意:有个#字型的棋盘,2行2列,一共24个格。
每个格子是1或2或3,一共8个1,8个2,8个3.
有A~H一共8种合法操作,比如A代表把A这一列向上移动一个,最上面的格会补到最下面。
求:使中心8个格子数字一致的最少步骤,要输出具体的操作步骤及最终中心区域的数字。如果有多个解,输出字典序最小的操作步骤。

思路:这个题目可以使用迭代加深搜索,时间复杂度也完全足够,这个方法的关键其实就是估价函数,也就是如果当前已经进行的操作次数,加上还需要的最小次数已经超过了当前的迭代层数就return,整个代码还是比较好写的。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <list>

#define MAXN 210
#define INF 10000000
#define MOD 1000000007
#define LL long long
#define pi acos(-1.0)

using namespace std;

int board[MAXN][MAXN] = {{0, 2, 6, 11, 15, 20, 22}, {1, 3, 8, 12, 17, 21, 23},
                         {10, 9, 8, 7, 6, 5, 4}, {19, 18, 17, 16, 15, 14, 13},
                         {23, 21, 17, 12, 8, 3, 1}, {22, 20, 15, 11, 6, 2, 0},
                         {13, 14, 15, 16, 17, 18, 19}, {4, 5, 6, 7, 8, 9, 10} };
int check_order[] = {6, 7, 8, 11, 12, 15, 16, 17};
int arr[MAXN];
char order[MAXN];

int falut_num() {
    int ans1 = 0, ans2 = 0, ans3 = 0;
    for (int i = 0; i < 8; ++i) {
        if (arr[check_order[i]] == 1)
            ans1++;
        else if (arr[check_order[i]] == 2)
            ans2++;
        else
            ans3++;
    }
    return 8 - max(max(ans1, ans2), ans3);
}

bool check() {
    for (int i = 0; i < 8; ++i) {
        if (arr[check_order[i]] != arr[check_order[0]])
            return false;
    }
    return true;
}

bool dfs(int x, int maxn) {
    if (x + falut_num() > maxn)
        return false;
    if (check())
        return true;
    int brr[MAXN];
    int temp[MAXN];
    memcpy(brr, arr, sizeof(arr));
    for (int i = 0; i < 8; ++i) {
        int cnt = 0;
        for (int j = 1; j < 7; ++j)
            temp[cnt++] = arr[board[i][j]];
        temp[cnt++] = arr[board[i][0]];
        for (int j = 0; j < 7; ++j) {
            arr[board[i][j]] = temp[j];
        }
        order[x] = (char)(i + 'A');
        if (dfs(x + 1, maxn))
            return true;
        memcpy(arr, brr, sizeof(brr));
    }
    return false;
}

int main() {
    std::ios::sync_with_stdio(false);
    while (cin >> arr[0] && arr[0]) {
        for (int i = 1; i < 24; ++i)
            cin >> arr[i];
        if (check()) {
            cout << "No moves needed\n";
            cout << arr[6] << endl;
        } else {
            int maxn = 0;
            while (true) {
                if (dfs(0, maxn))
                    break;
                maxn++;
            }
            order[maxn] = '\0';
            cout << order << endl;
            cout << arr[6] << endl;
        }
    }
    return 0;
}

/*
1 1 1 1 3 2 3 2 3 1 3 2 2 3 1 2 2 2 3 1 2 1 3 3
1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3
0
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值