八数码第三境界——暴力反向BFS+康托展开判重+打表
2017-12-13 16:49
513 查看
(在看了第1、2境界后,再看本文)
这里唯一新增的操作就是打表,所以需要理解打表这个概念。这里就是bfs找出所有的可能,并且都记录下来。
记录的方式。
vector<int>res
;
while(!q.empty())
{
g=q.front();q.pop();
int t = KT(g.str);
res[t] = g.res;
g.num++;
h=g;
if((h.index+1)%3!=0)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
h.index++;
h.res.push_back(4);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
第3行取得当前队首元素。
第4行取得这个队首元素对应的康托位置。
第5行通过这个位置,在res中记录下这个它走到这一步的操作。
bfs跑完后的比对操作
t = KT(ss);
if(res[t].size()!=0||t==46234)
for(i=res[t].size()-1;i>=0;i--)
{
if(res[t][i]==1)printf("d");
if(res[t][i]==2)printf("u");
if(res[t][i]==3)printf("r");
if(res[t][i]==4)printf("l");
}
else
printf("unsolvable");
通过你所要求的康托位置,找找看有没有这种可能,有的话就输出他,很简单。
全部代码
#define N 512345
char ss[10];
struct node
{
char str[10];
vector<int>res;
int index,num;
};
vector<int>res
;
bool vis
;
int fac[] = {1,1,2,6,24,120,720,5040,40320};
int over;
int ans
;
int KT(char ss[])
{
int i, j, t, sum;
int s[10];
for(i=0;i<9;i++)
{
if(ss[i]=='x')
s[i]=0;
else
s[i]=ss[i]-'0';
}
sum = 0;
for (i=0; i<9; i++)
{
t = 0;
for (j=i+1; j<9; j++)
if (s[j] < s[i])
t++;
sum += t*fac[9-i-1];
}
return sum+1;
}
bool bfs()
{
char c;
queue<node> q;
while(!q.empty())q.pop();
over = KT(ss);
node g,h;
for(int i=0;i<8;i++)
g.str[i]=i+1+'0';
g.str[8]='x';g.str[9]='\0';
g.res.clear();g.index=8;g.num=0;
int t=KT(g.str);
vis[t] = true;
q.push(g);
while(!q.empty())
{
g=q.front();q.pop();
int t = KT(g.str);
res[t] = g.res;
g.num++;
h=g;
if((h.index+1)%3!=0)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
h.index++;
h.res.push_back(4);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
h=g;
if(h.index%3!=0)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index-1];h.str[h.index-1]=c;
h.index--;
h.res.push_back(3);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
h=g;
if(h.index<6)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index+3];h.str[h.index+3]=c;
h.index+=3;
h.res.push_back(2);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
h=g;
if(h.index>2)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index-3];h.str[h.index-3]=c;
h.index-=3;
h.res.push_back(1);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
}
return false;
}
int main()
{
int i,j,k,kk,t,x,y,z;
for(i=0;i<N;i++)
res[i].clear();
bfs();
while(scanf("%s",ss)!=EOF)
{
memset(vis,false,sizeof(vis));
for(i=1;i<9;i++)
scanf("%s",ss+i);
t = KT(ss);
if(res[t].size()!=0||t==46234)
for(i=res[t].size()-1;i>=0;i--)
{
if(res[t][i]==1)printf("d");
if(res[t][i]==2)printf("u");
if(res[t][i]==3)printf("r");
if(res[t][i]==4)printf("l");
}
else
printf("unsolvable");
printf("\n");
}
return 0;
}
这里唯一新增的操作就是打表,所以需要理解打表这个概念。这里就是bfs找出所有的可能,并且都记录下来。
记录的方式。
vector<int>res
;
while(!q.empty())
{
g=q.front();q.pop();
int t = KT(g.str);
res[t] = g.res;
g.num++;
h=g;
if((h.index+1)%3!=0)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
h.index++;
h.res.push_back(4);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
第3行取得当前队首元素。
第4行取得这个队首元素对应的康托位置。
第5行通过这个位置,在res中记录下这个它走到这一步的操作。
bfs跑完后的比对操作
t = KT(ss);
if(res[t].size()!=0||t==46234)
for(i=res[t].size()-1;i>=0;i--)
{
if(res[t][i]==1)printf("d");
if(res[t][i]==2)printf("u");
if(res[t][i]==3)printf("r");
if(res[t][i]==4)printf("l");
}
else
printf("unsolvable");
通过你所要求的康托位置,找找看有没有这种可能,有的话就输出他,很简单。
全部代码
#define N 512345
char ss[10];
struct node
{
char str[10];
vector<int>res;
int index,num;
};
vector<int>res
;
bool vis
;
int fac[] = {1,1,2,6,24,120,720,5040,40320};
int over;
int ans
;
int KT(char ss[])
{
int i, j, t, sum;
int s[10];
for(i=0;i<9;i++)
{
if(ss[i]=='x')
s[i]=0;
else
s[i]=ss[i]-'0';
}
sum = 0;
for (i=0; i<9; i++)
{
t = 0;
for (j=i+1; j<9; j++)
if (s[j] < s[i])
t++;
sum += t*fac[9-i-1];
}
return sum+1;
}
bool bfs()
{
char c;
queue<node> q;
while(!q.empty())q.pop();
over = KT(ss);
node g,h;
for(int i=0;i<8;i++)
g.str[i]=i+1+'0';
g.str[8]='x';g.str[9]='\0';
g.res.clear();g.index=8;g.num=0;
int t=KT(g.str);
vis[t] = true;
q.push(g);
while(!q.empty())
{
g=q.front();q.pop();
int t = KT(g.str);
res[t] = g.res;
g.num++;
h=g;
if((h.index+1)%3!=0)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
h.index++;
h.res.push_back(4);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
h=g;
if(h.index%3!=0)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index-1];h.str[h.index-1]=c;
h.index--;
h.res.push_back(3);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
h=g;
if(h.index<6)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index+3];h.str[h.index+3]=c;
h.index+=3;
h.res.push_back(2);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
h=g;
if(h.index>2)
{
c=h.str[h.index];h.str[h.index]=h.str[h.index-3];h.str[h.index-3]=c;
h.index-=3;
h.res.push_back(1);
int t=KT(h.str);
if(!vis[t])
{
vis[t]=true;
q.push(h);
}
}
}
return false;
}
int main()
{
int i,j,k,kk,t,x,y,z;
for(i=0;i<N;i++)
res[i].clear();
bfs();
while(scanf("%s",ss)!=EOF)
{
memset(vis,false,sizeof(vis));
for(i=1;i<9;i++)
scanf("%s",ss+i);
t = KT(ss);
if(res[t].size()!=0||t==46234)
for(i=res[t].size()-1;i>=0;i--)
{
if(res[t][i]==1)printf("d");
if(res[t][i]==2)printf("u");
if(res[t][i]==3)printf("r");
if(res[t][i]==4)printf("l");
}
else
printf("unsolvable");
printf("\n");
}
return 0;
}
相关文章推荐
- 八数码第四境界——暴力反向BFS+康托展开判重+打表+回溯记录路径
- 八数码第二境界——暴力反向BFS+康托展开判重
- HDU 1043 Eight(八数码第三境界|广搜+哈希+打表)
- 八数码第一境界——暴力反向BFS+存状态
- 八数码第五境界——双向BFS+康托展开判重+回溯记录路径
- HDU 1043 Eight(八数码第五境界|A*+哈希+简单估价函数+打表)
- uva1583(暴力枚举或打表)
- 八数码的八境界
- 八数码问题bfs暴力破解(java实现)
- HDU-1043:Eight(八数码+bfs(反向或A*))
- 八数码的八境界
- hdu2089 不要62(暴力打表计数,数位DP)
- HDU 5812 Distance 暴力+素数打表
- hdu5451 矩阵快速幂+暴力打表循环节
- ZOJ.2421 Recaman's Sequence【暴力打表】 2015/09/24
- POJ1077&HDU1043 Eight 八数码第八境界 IDA* hash 康托展开 奇偶剪枝
- hdoj 1431 素数回文 【暴力打表】
- c++ primer第五版(中文)习题答案 第十章第四节第三小节-反向迭代器
- HDU 2510 符号三角形 暴力打表
- 我的基金第三境界 基金定投收益计算公式