1151. 魔板[Speical judge]

本文介绍了一种基于康托编码的魔方求解算法,利用阶乘数组进行状态标识,并通过队列实现状态搜索。文章详细阐述了如何通过不同的操作变换魔方状态,最终找到从初始状态到达目标状态的操作序列。

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

#include <iostream>
#include <cstring> //include <string.h> 
#include <queue>
using namespace std;

int factorial[10];
queue<int> q;

struct Node
{
       char board[10];   //重点1:node下标代表康拓编码,board代表魔板状态 
       int step;         //step 代表多少步转变 
       int vis;          //vis代表是否存在模版状态 
       char record[100]; //record代表操作 
}node[50000];            //重点2:由于使用了康托编码,空间 大大节省,最多有 8! 种情况

 //生成 0到 8的阶乘数组
void init_array()                
{
    int sum = 1;  
    factorial[0] = 1;
    for (int i = 1; i <= 8; i++)
    {
        sum *= i;      
        factorial[i] = sum;
    }    
}

//重点3:康拓编码,获得魔板状态的康拓编码 
int getId(char c[])        
{
    bool used[10];
    int id; 
    memset(used, false, sizeof(used));
    
    id = 0;
    for (int i = 0; i < 8; i ++)
    {
        for (int j = 1; j < c[i] - '0'; j ++)
        if (!used[j])
        id += factorial[7 - i];     
        used[c[i] - '0'] = true;   
    }   
    return id;
}

//初始化node数组以及队列q的状态 
void init()                   
{
     init_array();
     
     for (int i = 0; i < 50000; i ++)
     {
         node[i].vis = false;
         node[i].step = 0;
         node[i].record[0] = '\0';
     }    
     while (!q.empty())
     q.pop();
}

void operate1(char temp[], int fa)
{
    int idx;
    
    for (int i = 0; i < 4; i ++)
    //重点4:swap交换函数C语言 #include <string.h>或者#include <algorithm.h> 
    swap(temp[i], temp[i + 4]);
    
    idx = getId(temp);
    
    if (!node[idx].vis)
    {
         strcpy(node[idx].board, temp);   
         strcpy(node[idx].record, node[fa].record);           
         node[idx].step = node[fa].step + 1;
         node[idx].record[node[idx].step - 1] = 'A';
         node[idx].record[node[idx].step] = '\0';
         node[idx].vis = true;
         q.push(idx);
    }
}

void operate2(char temp[], int fa)
{
     int idx;
     char t1, t2;
     
     t1 = temp[3];
     t2 = temp[7]; 
     
     for (int i = 3; i >= 1; i --)
     {
         temp[i] = temp[i - 1];
         temp[i + 4] = temp[i + 3];
     }
     
     temp[0] = t1;
     temp[4] = t2;
     
     idx = getId(temp);
     
     if (!node[idx].vis)
     {
          strcpy(node[idx].board, temp);
          strcpy(node[idx].record, node[fa].record);
          node[idx].step = node[fa].step + 1;
          node[idx].record[node[idx].step - 1] = 'B';
          node[idx].record[node[idx].step] = '\0';
          node[idx].vis = true;
          q.push(idx);
     }
}

void operate3(char temp[], int fa)
{
     int idx;
     char t;
     
     t = temp[1];
     
     temp[1] = temp[5];
     temp[5] = temp[6];
     temp[6] = temp[2];
     temp[2] = t;
     
     idx = getId(temp);
     
     if (!node[idx].vis)
     {
          strcpy(node[idx].board, temp);
          strcpy(node[idx].record, node[fa].record);
          node[idx].step = node[fa].step + 1;
          node[idx].record[node[idx].step - 1] = 'C';
          node[idx].record[node[idx].step] = '\0';
          node[idx].vis = true;
          q.push(idx);
     }
}

int main()
{
    init_array();   
    int N;
    char begin[10];
    char goal[10];
    char hold[10];
    int idx;
    
    while(1) 
    {
          cin >> N;
          if(N==-1)
             break;
          init();
          //字符初始化 
          for (int i = 0; i < 4; i ++) 
               begin[i] = (i + 1) + '0';
          for (int i = 4; i < 8; i ++)
               begin[11 - i] = (i + 1) + '0';
          begin[8] = '\0';
          
          for (int i = 0; i < 8; i ++)
               cin >> goal[i]; 
          goal[8] = '\0';
          
          //获得begin字符串的康拓编码 
          idx = getId(begin); 
          
          strcpy(node[idx].board,begin);
          node[idx].vis = true;
         
          //队列存储康拓编码 
          q.push(idx); 
          
          while (!q.empty())
          {
                idx = q.front();
                
                //重:5:strcmp功能:比较字符串s1和s2。当s1<s2时,返回值<0;当s1=s2时,返回值=0;当s1>s2时,返回值>0 
                //属于C语言,因此需要#include <string.h> 
                if (strcmp(node[idx].board, goal) == 0) 
                {
                    if (node[idx].step <= N)
                        cout << node[idx].step<<" " << node[idx].record <<endl; 
                    //printf("%d %s\n", node[idx].step, node[idx].record);
                    else
                        cout << -1 <<endl;
                    break;
                }
                //重点6:strcmp功能:复制字符串 
                //属于C语言,因此需要#include <string.h> 
                strcpy(hold, node[idx].board);
                operate1(hold, idx);
                strcpy(hold, node[idx].board);
                operate2(hold, idx);
                strcpy(hold, node[idx].board);
                operate3(hold, idx);
                
                q.pop();
          }
    }
    
    return 0;
}

内容概要:该论文研究增程式电动汽车(REEV)的能量管理策略,针对现有优化策略实时性差的问题,提出基于工况识别的自适应等效燃油消耗最小策略(A-ECMS)。首先建立整车Simulink模型和基于规则的策略;然后研究动态规划(DP)算法和等效燃油最小策略;接着通过聚类分析将道路工况分为四类,并设计工况识别算法;最后开发基于工况识别的A-ECMS,通过高德地图预判工况类型并自适应调整SOC分配。仿真显示该策略比规则策略节油8%,比简单SOC规划策略节油2%,并通过硬件在环实验验证了实时可行性。 适合人群:具备一定编程基础,特别是对电动汽车能量管理策略有兴趣的研发人员和技术爱好者。 使用场景及目标:①理解增程式电动汽车能量管理策略的基本原理;②掌握动态规划算法和等效燃油消耗最小策略的应用;③学习工况识别算法的设计和实现;④了解基于工况识别的A-ECMS策略的具体实现及其优化效果。 其他说明:此资源不仅提供了详细的MATLAB/Simulink代码实现,还深入分析了各算法的原理和应用场景,适合用于学术研究和工业实践。在学习过程中,建议结合代码调试和实际数据进行实践,以便更好地理解策略的优化效果。此外,论文还探讨了未来的研究方向,如深度学习替代聚类、多目标优化以及V2X集成等,为后续研究提供了思路。
内容概要:论文《基于KANN-DBSCAN带宽优化的核密度估计载荷谱外推》针对传统核密度估计(KDE)载荷外推中使用全局固定带宽的局限性,提出了一种基于改进的K平均最近邻DBSCAN(KANN-DBSCAN)聚类算法优化带宽选择的核密度估计方法。该方法通过对载荷数据进行KANN-DBSCAN聚类分组,采用拇指法(ROT)计算各簇最优带宽,再进行核密度估计和蒙特卡洛模拟外推。实验以电动汽车实测载荷数据为对象,通过统计参数、拟合度和伪损伤三个指标验证了该方法的有效性,误差显著降低,拟合度R²>0.99,伪损伤接近1。 适合人群:具备一定编程基础和载荷数据分析经验的研究人员、工程师,尤其是从事汽车工程、机械工程等领域的工作1-5年研发人员。 使用场景及目标:①用于电动汽车载荷谱编制,提高载荷预测的准确性;②应用于机械零部件的载荷外推,特别是非对称载荷分布和多峰扭矩载荷;③实现智能网联汽车载荷预测与数字孪生集成,提供动态更新的载荷预测系统。 其他说明:该方法不仅解决了传统KDE方法在复杂工况下的“过平滑”与“欠拟合”问题,还通过自适应参数机制提高了方法的普适性和计算效率。实际应用中,建议结合MATLAB代码实现,确保数据质量,优化参数并通过伪损伤误差等指标进行验证。此外,该方法可扩展至风电装备、航空结构健康监测等多个领域,未来研究方向包括高维载荷扩展、实时外推和多物理场耦合等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值