让我先分分钟剖腹自尽。
然后大力鸣谢@yangyihua 大家来找茬的 擅长者。
还有 @ Mr.Sirius 花了 他 N++个小时 还害他 差点改姓 智 了 、。。。(^o^)/~【【这么说 应该让他改的】】
这道题 改了 n++ 个小时。
题目:
戳戳戳
题意:
这道题,大概就是要把中间的8个数字变成一样的,输出操作和步数。
分析:
搜索啊! 但是简单暴搜 估计会挂。
所以我们用 ID + A* 【【我是不会告诉你们我一直不知道是这俩的(^o^)/~】】
估价函数:
跟大多数的人大概不太一样。记录最少不一样的。如果当前步数+你的估价>你循环的最大步数。就return false
容易错的【【或者只是我错的
1. 没有看到 不用动 就输出 No moves needed
2. 没有输出 中间的数字
3. 不应输出也要输出中间的数字
4. 然后搜完了所有的,我竟然没有 返回false !!!!!!N+N 次。别拦着我,让我从8楼跳下去。~~o(>_<)o ~~
5. 表打错了 【(⊙﹏⊙)b
6. 然后从0开始和从1开始
你问我怎么错的这么多?
有图有真相:
然后贴份代码,写的特别好的:
#include<cstdio>
#include<algorithm>
#include<cstring>
//by mars_ch
using namespace std;
int biao[8][8]=
{
{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
{23,21,17,12,8,3,1},//E
{22,20,15,11,6,2,0}, //F
{13,14,15,16,17,18,19}, //G
{4,5,6,7,8,9,10},//H
};
int cen[8]={6,7,8,11,12,15,16,17};
int p[25],num;
char put[1005];
bool ok()
{
for(int i=0;i<8;i++){
if(p[cen[i]] !=p[cen[0]])
return false;}
return true;
}
int cnt()
{
num=10000;
for(int i=1;i<=3;i++)
{
int temp=0;
for(int j=0;j<8;j++)
{
if(p[cen[j]] != i)
temp++;
}
num=min(num,temp);
}
return num;
}
void move(int a)
{
int temp=p[biao[a][0]];
for(int i=0;i<6;i++)
{
p[biao[a][i]]=p[biao[a][i+1]];
}
p[biao[a][6]]=temp;
}
bool dfs(int cd,int md) //current depth & max depth
{
if(cd == md)
{
if(ok() == 1)
{
put[cd]='\0';
printf("%s\n%d\n",put,p[cen[0]]);
return true;
}
else return false;
}
if(cd+cnt()>md) return false;
for(int i=0;i<8;i++)
{
put[cd]='A'+i;
move(i);
if(dfs(cd+1,md) == 1) return 1;
if(i % 2 ==0) move((i+5)%8);
else move((i+3)%8); //这是啥,反向操作啊!4组:0,5;1,4;2,7;3,6;
}
return false;
}
int main()
{
while(scanf("%d",&p[0]) && p[0]!=0)
{
for(int i=1;i<24;i++)
{
scanf("%d",&p[i]);
}
if(ok() == 1) printf("No moves needed\n%d\n",p[cen[0]]);
else{
for(int i=1;i<=1005;i++)
{
if(dfs(0,i) == 1) break;
}
}
}
return 0;
}
我放弃了 缩代码这个 艰巨的任务
6.1儿童节有人送礼物吗?!