题意:
给出一个2X2X2的魔方,再给一个限定的步骤长度,不超过该长度最多能能使几个面拼成功。
纯粹模拟题,搞清楚几个面的变换关系,并化简步骤,三种旋转方式,两种旋转方向。bfs,dfs都可以。
#include <stdio.h>
#include <string.h>
#define maxn 300000
int twist[3][3][4]=
{
{{1,7,17,21}, {3,13,19,23}, {9,8,14,15}},
{{2,11,17,8}, {3,5,16,14}, {6,12,13,7}},
{{0,2,3,1}, {23,4,6,8}, {22,5,7,9} },
};
struct P{
int state[24];
int step;
}p[maxn];
int usage[24];
int head,tail,N,ans;
int judge(int *a)
{
int ans=0;
if(a[0]==a[1] && a[0]==a[2] && a[0]==a[3])
ans++;
if(a[4]==a[5] && a[4]==a[10] && a[4]==a[11])
ans++;
if(a[6]==a[7] && a[6]==a[12] && a[6]==a[13])
ans++;
if(a[8]==a[9] && a[8]==a[14] && a[8]==a[15])
ans++;
if(a[16]==a[17]&&a[16]==a[18]&& a[16]==a[19])
ans++;
if(a[20]==a[21]&&a[20]==a[22]&& a[20]==a[23])
ans++;
return ans;
}
int bfs()
{
head=0,tail=1;
int i,j,k;
int index,tt;
p[0].step=0;
/* for(k=0;k<24;k++)
printf("%2d ",k);
printf("\n");
for(k=0;k<24;k++)
printf("%2d ",p[0].state[k]);
printf("\n");*/
ans=judge(p[0].state);
while(head<tail)
{
if(p[head].step==N||ans==6)
break;
for(i=0;i<3;i++)
{
memcpy(usage,p[head].state,sizeof(usage));
for(j=0;j<3;j++)
{
for(k=1;k<4;k++)
{
index=twist[i][j][k];
tt=usage[twist[i][j][0]];
usage[twist[i][j][0]]=usage[index];
usage[index]=tt;
}
}
k=judge(usage);
ans=ans>k?ans:k;
if(p[head].step + 1 < N)
{
memcpy(p[tail].state,usage,sizeof(usage));
p[tail++].step=p[head].step+1;
}
for(j=0;j<3;j++)
{
for(k=1;k<4;k++)
{
index=twist[i][j][k];
tt=usage[twist[i][j][0]];
usage[twist[i][j][0]]=usage[index];
usage[index]=tt;
}
}
for(j=0;j<3;j++)
{
for(k=1;k<4;k++)
{
index=twist[i][j][k];
tt=usage[twist[i][j][0]];
usage[twist[i][j][0]]=usage[index];
usage[index]=tt;
}
}
k=judge(usage);
ans=ans>k?ans:k;
if(p[head].step + 1 < N)
{
memcpy(p[tail].state,usage,sizeof(usage));
p[tail++].step=p[head].step+1;
}
}
head++;
}
return ans;
}
int main(){
//freopen("D:\\a.txt","w",stdout);
int i,n;
while(scanf("%d",&N)!=EOF)
{
for(i=0;i<24;i++)
scanf("%d",p[0].state+i);
n=bfs();
printf("%d\n",n);
}
return 0;
}