hdu1667 The Rotation Game
Posted liguanlin1124
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu1667 The Rotation Game相关的知识,希望对你有一定的参考价值。
题目描述:
你有一个#。有8个不同方向可以动,编号依次为A-H。求使其中心8个块数字变成相同时,最短字典序最小的字符串以及中心的数字。
题解:
对于这种状态极为发散的搜索,我们可使用A*。而这道题要求最短,我们可以采用IDA*。
估价函数h=8-(中心块上出现最多的数的出现次数)。
因为每动一次只踢出去一个格,拉进来一个格。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int rnd[10][10]={{},{1,3,7,12,16,21,23},{2,4,9,13,18,22,24},{11,10,9,8,7,6,5},{20,19,18,17,16,15,14},{24,22,18,13,9,4,2},{23,21,16,12,7,3,1},{14,15,16,17,18,19,20},{5,6,7,8,9,10,11}}; struct jr { int a[25]; int ans[25],g; int h() { int cnt[4]={0,0,0,0}; cnt[a[7]]++,cnt[a[8]]++,cnt[a[9]]++; cnt[a[12]]++,cnt[a[13]]++; cnt[a[16]]++,cnt[a[17]]++,cnt[a[18]]++; return 8-max(cnt[1],max(cnt[2],cnt[3])); } void trn(int k) { for(int i=1;i<=6;i++) swap(a[rnd[k][i-1]],a[rnd[k][i]]); } }j0; int lim; bool fg; void dfs(jr u) { int hh = u.h(); if(!hh) { for(int i=1;i<=u.g;i++)printf("%c",‘A‘+u.ans[i]-1); printf(" %d ",u.a[7]); fg=1; return ; } if(u.g+hh>lim)return ; if(fg)return ; jr tmp; for(int k=1;k<=8;k++) { tmp = u; tmp.ans[++tmp.g]=k; tmp.trn(k); dfs(tmp); } } int main() { while(scanf("%d",&j0.a[1])&&scanf("%d",&j0.a[2])>0) { for(int i=3;i<=24;i++)scanf("%d",&j0.a[i]); j0.g=0; if(j0.h()==0) { printf("No moves needed %d ",j0.a[7]); continue; } for(lim=1,fg=0;!fg;lim++) { dfs(j0); } } return 0; }
以上是关于hdu1667 The Rotation Game的主要内容,如果未能解决你的问题,请参考以下文章