The Rotation Game UVA - 1343 IDA*

4 篇文章 0 订阅

紫书代码详见代码内注释

 

 

#include<bits/stdc++.h>
using namespace std;
int a[24];
char ans[1050];

/* 坐标分布图
      00    01
      02    03
04 05 06 07 08 09 10
      11    12
13 14 15 16 17 18 19
      20    21
      22    23
*/

int line[8][7]={
  { 0, 2, 6,11,15,20,22}, // A
  { 1, 3, 8,12,17,21,23}, // B
  {10, 9, 8, 7, 6, 5, 4}, // C
  {19,18,17,16,15,14,13}, // D
};




const int center[8] = {6, 7, 8, 11, 12, 15, 16, 17}; //中心的坐标
bool is_final(){  //判断是否达成结果
for(int i=0;i<8;i++){
    if(a[center[i]]!=a[center[0]]){
        return 0;
    }
}

return 1;
}
int dff(int x){   //和h()配合使用
    int cnt=0;
for(int i=0;i<8;i++){
    if(a[center[i]]!=x){cnt++;}
}
return cnt;

}


int h(){
return min(min(dff(1),dff(2)),dff(3));  //找出三个数字中对应成功最少的
}



void move(int i){  //环状移动
int tmp=a[line[i][0]];
for(int j=0;j<6;j++){
    a[line[i][j]]=a[line[i][j+1]];
}
a[line[i][6]]=tmp;
}


const int rev[8] = {5, 4, 7, 6, 1, 0, 3, 2};  //对面的line里面的i操作 例如line 里面i==0时为A操作而F操作才能使还原所以才rev里i==0时rev[0]==5代表line[5]的F操作

bool dfs(int d,int maxd){
if(is_final()){   //达成后把字符数组以字符串形式输出
    ans[d]='\0';
    printf("%s\n",ans);
    return 1;
}
if(d+h()>maxd)return 0; //剪枝  剩余最大操作数小于错误数肯定就能直接剪
for(int i=0;i<8;i++){
    ans[d]='A'+i;
    move(i);     
    if(dfs(d+1,maxd))return 1;
    move(rev[i]);
}
return 0;
}




int main(){
    for(int i=4;i<8;i++)
    for(int j=0;j<7;j++){
        line[i][j]=line[rev[i]][6-j];  //减少人工,把EFGH的标号弄出来
    }

while(scanf("%d",&a[0])==1&&a[0]){
        for(int i=1;i<24;i++)scanf("%d",&a[i]);
for(int i=0;i<24;i++){
    if(!a[i])return 0;
}
if(is_final()){
    printf("No moves needed\n");
}
else {
    for(int maxd=1;;maxd++){//一定有解 不用设置上限
      if(dfs(0,maxd))break;
    }
   
}
 printf("%d\n",a[8]);

}

return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值