问题描述
【题目描述】
【输出】
题目解析
- 定义 s t a r t start start这个初始状态, f r o n t front front头指针指向初始状态。
- 对这个初始状态分别做上层旋转、右层旋转、前层旋转,试图加入set集合中,如果之前从未出现过该序列则加入成功, t a i l tail tail尾指针++, f r o n t front front++;
- 不断重复步骤2直到 t a i l = = f r o n t tail==front tail==front,此时 f r o n t front front就表示加入的总状态数,即为所求。
C++代码
#include<bits/stdc++.h>
using namespace std;
typedef char st[8][7];
st start = {{"oybbgb"},{"oygbbb"},{"bygbby"},{"bybbgy"},{"obbogb"},{"obgobb"},{"bbgoby"},{"bbbogy"}};
st q[4000000];
set<string> all_state;
int ans,front,tail;
string to_string(st &a)
{
string ans;
for(int i=0;i<8;i++) ans+=a[i];
return ans;
}
void ucell(char *a) //上层的块的旋转,面的相对位置调换
{
swap(a[0],a[2]);
swap(a[2],a[5]);
swap(a[5],a[4]);
}
void u(st &s) //上层顺时针旋转
{
ucell(s[0]);
ucell(s[1]);
ucell(s[2]);
ucell(s[3]);
//块的相对位置调换
swap(s[1],s[0]);
swap(s[2],s[1]);
swap(s[3],s[2]);
}
void rcell(char *a) //右层的块的旋转,面的相对位置调换
{
swap(a[1],a[0]);
swap(a[0],a[3]);
swap(a[3],a[5]);
}
void r(st &s) //右层旋转面的相对位置变化
{
rcell(s[1]);
rcell(s[2]);
rcell(s[6]);
rcell(s[5]);
//块的相对位置调换
swap(s[2],s[1]);
swap(s[5],s[1]);
swap(s[6],s[5]);
}
void fcell(char *a) //前层的块的旋转,面的相对位置调换
{
swap(a[2],a[1]);
swap(a[1],a[4]);
swap(a[4],a[3]);
}
void f(st &s) //前层旋转面的相对位置变化
{
fcell(s[0]);
fcell(s[1]);
fcell(s[4]);
fcell(s[5]);
//块的相对位置调换
swap(s[1],s[5]);
swap(s[0],s[1]);
swap(s[4],s[0]);
}
void uwhole(st &s) //整个魔方从顶部看顺时针转用于判重
{
u(s); //上层旋转
//下层旋转
ucell(s[4]);
ucell(s[5]);
ucell(s[6]);
ucell(s[7]);
//块的变动
swap(s[5],s[4]);
swap(s[6],s[5]);
swap(s[7],s[6]);
}
void fwhole(st &s) //整个魔方从前面看顺时针转用于判重
{
f(s);
fcell(s[2]);
fcell(s[6]);
fcell(s[7]);
fcell(s[3]);
swap(s[2],s[6]);
swap(s[3],s[2]);
swap(s[7],s[3]);
}
void rwhole(st &s) //整个魔方从右面看顺时针转用于判重
{
r(s);
rcell(s[3]);
rcell(s[0]);
rcell(s[4]);
rcell(s[7]);
swap(s[3],s[7]);
swap(s[0],s[3]);
swap(s[4],s[0]);
}
bool try_insert(st &s)
{
st k;
memcpy(k,s,sizeof(start));
for(int i=0;i<4;i++)
{
fwhole(k);
for(int j=0;j<4;j++)
{
uwhole(k);
for(int q=0;q<4;q++)
{
rwhole(k);
if(all_state.count(to_string(k))==1) return false;
}
}
}
all_state.insert(to_string(k));
return true;
}
void solve()
{
front = 0;
tail = 1;
all_state.insert(to_string(start));
memcpy(q[front],start,sizeof(start)); //填充q[0]
while(front<tail)
{
memcpy(q[tail],q[front],sizeof(start)); //拷贝到tail
u(q[tail]); //上层顺时针旋转
if(try_insert(q[tail])) tail++;//扩展队列
memcpy(q[tail],q[front],sizeof(start)); //拷贝到tail
r(q[tail]); //右层顺时针旋转
if(try_insert(q[tail])) tail++; //扩展队列
memcpy(q[tail],q[front],sizeof(start)); //拷贝到tail
f(q[tail]); //前顺时针旋转
if(try_insert(q[tail])) tail++; //扩展队列
front++; //弹出队首
cout<<front<<" "<<tail<<endl;
}
cout<<front<<endl;
}
int main()
{
solve();
return 0;
}
正确答案
该代码跑出来需要一定时间,大家一定要耐心等待~
原文参考链接