1150. 简单魔板[Special judge]

本文介绍了一种基于特定判断的简单魔板问题解决方案,通过结构体定义节点并利用三种基本操作实现状态转移,在限定步数内寻找从初始状态到达目标状态的有效路径。

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

/*
1150. 简单魔板[Special judge] 
题目大意:
        给出魔板的起始状态,并给定三种基本操作,给出一个步数上限和目标状态,求从起始状态到目标状态的操作序列,长度不得超过上限。
解题思路:
        对模板进行状态搜索;
        由一种状态可以转移到另外三种状态,搜索树为一棵三叉树;
        在这棵三叉树上搜索,目的是求出最优解。

*/
#include <iostream>
#include <cmath> 
using namespace std;

//1.重点: 熟悉结构体 
struct node{
    int x;
    int y;
    char op;
    int pre;
};

//2.重点:关键是传引用,注意main函数的变量也是局部变量,其他函数不能直接使用 
void OPA(int& tempX,int& tempY){
     int t;
     t= tempX;
     tempX = tempY;
     tempY = t; 

} 
void OPB(int& tempX,int& tempY){
     tempX=(tempX % 10) *1000+(tempX / 10);
     tempY=(tempY % 10) *1000+(tempY / 10);
} 
void OPC(int& tempX,int& tempY){
     int i,j,a,b,i1,j1,c,d;
     i=(tempX / 1000)*1000;  
     j=tempX-i; a=j/100; 
     b=(j-a*100)/10;
     i1=(tempY / 1000)*1000;
     j1=tempY-i1;
     c=j1 / 100;
     d=(j1-c*100) / 10;
     tempX=i+c*100+a*10+(tempX % 10);
     tempY=i1+d*100+b*10+(tempY % 10);
} 

//3.重点:传数组是传指针 
void Printop(node nodelist[],int rp,char sop[]){     
     int j=1;
     int i;
     i = nodelist[rp].pre;
     sop[j] = nodelist[rp].op;
     while(i!=0){
         j=j+1;
         sop[j]=nodelist[i].op;
         i = nodelist[i].pre;
     }
	 cout << (j-1) <<" ";
//4.重点:要学会设计循环,有很多微妙的错误 
	 for (int k=j-1;1<=k;k--){
         cout << sop[k] ;
     }
	 cout << endl;
}


int main(){
    
    char a,b,c,d,e,f,g,h;
    
    int panduanX;
    int panduanY;
    int tempX,tempY;
    int N;//最多步数 
    int M;//实际步数 
    int fp;
    int rp;
    //5、重点:一般直接将数组定为100000,也就是十万,解决(Runtime Error)数组溢出; 
    struct node nodelist[100000];
    char sop[100000];
    bool flag;
    bool flag1;
    //6、重点:将循环内容定为数组,后面使用求模来跳过某些循环 
    char op[3]={'A','B','C'};
    
    while(1){
         cin >> N;
         if(N==-1)
              break;
         cin >> a >> b >> c >>d;
         cin >> e >> f >> g >>h;
         //int a,b,c,d
         // panduan = a*1000+b*100+c*10+d;  
         panduanX=(a-'0')*1000+(b-'0')*100+(c-'0')*10+(d-'0');
         panduanY=(e-'0')*1000+(f-'0')*100+(g-'0')*10+(h-'0');   
         // 1.错误:nodelist[1]={1234,5678,'-',0};结构数组不能直接这样子赋值 
         nodelist[1].x=1234;
         nodelist[1].y=8765;
         nodelist[1].op='-';
         nodelist[1].pre=0;
         fp = 1;
         rp = 1;
         flag= true;
         flag1=true;
         // 2.错误:应该使用pow函数算幂函数(#include <cmath>)    
         for(int t=0;t<(int)pow(3,(double)N);t++){
             tempX = nodelist[fp].x;
             tempY = nodelist[fp].y;
             if(op[t%3]=='A')
                  OPA(tempX,tempY);
             if(op[t%3]=='B')
                  OPB(tempX,tempY);
             if(op[t%3]=='C')
                  OPC(tempX,tempY);
             flag = true;
    
             for(int i=1;i<=rp;i++){
                  if(tempX == nodelist[i].x && tempY == nodelist[i].y){
                         flag = false;
						 break;
                  }
             } 
             if(flag==true){
                   
                   rp = rp + 1;
                   nodelist[rp].x=tempX;
                   nodelist[rp].y=tempY;
                   nodelist[rp].op=op[t%3];
                   nodelist[rp].pre=fp;
                         
                  if(tempX==panduanX && tempY==panduanY){
                       flag1 = false;
                       Printop(nodelist,rp,sop);
					   break;
					   //7、重点:使用break跳出循环 
                  }                  
            }
            //8.重点:求模的重要性 
            if(t!=0 && (t+1)%3==0)
                fp++;
        }
        
        if(flag1==true){
            cout << -1 <<endl;
        }             
    }    
     return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值