紫书搜索 例题7-12 UVA - 1343 The Rotation Game IDA*迭代加深搜索

    xiaoxiao2021-03-25  71

    题目链接:

    https://vjudge.net/problem/UVA-1343

    题意:

    数字1,2,3都有八个,求出最少的旋转次数使得图形中间八个数相同。 旋转规则:对于每一长行或每一长列,每次旋转就是将数据向头的位置移动一位,头上的数放置到尾部。若次数相同,则找出字典序最小旋转次序。 输入是从上到下,从左向右,注意方向

    题解:

    代码:

    #include <bits/stdc++.h> using namespace std; typedef long long ll; #define MS(a) memset(a,0,sizeof(a)) #define MP make_pair #define PB push_back const int INF = 0x3f3f3f3f; const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ////////////////////////////////////////////////////////////////////////// const int maxn = 1e5+10; int maxd,ok,a[50]; char ans[maxn]; int line[8][7] = { {0,2,6,11,15,20,22}, {1,3,8,12,17,21,23}, {10,9,8,7,6,5,4}, {19,18,17,16,15,14,13} }; int rev[8] = {5,4,7,6,1,0,3,2}; // 通过A,B,C,D,反推其他方向。指向反向,用来还原现场。 int final[8] = {6,7,8,11,12,15,16,17}; // 最后答案要求的点 void init(){ // 反推方向 for(int i=4; i<8; i++) for(int j=0; j<=6; j++) line[i][j] = line[rev[i]][6-j]; } bool is_final(){ int k = a[final[0]]; for(int i=1; i<8; i++) if(a[final[i]]!=k) return false; return true; } void move(int k){ int tmp = a[line[k][0]]; for(int i=1; i<7; i++) a[line[k][i-1]] = a[line[k][i]]; a[line[k][6]] = tmp; } int diff(int x){ int cnt = 0; for(int i=0; i<8; i++) if(x != a[final[i]]) cnt++; return cnt; } int h(){ //估值函数 return min(min(diff(1),diff(2)),diff(3)); } void dfs(int cur){ if(is_final()){ ans[cur] = '\0'; cout << ans << endl; ok = 1; return ; } if(cur+h() > maxd) return ; //剪枝 for(int i=0; i<8; i++){ ans[cur] = 'A'+i; move(i); dfs(cur+1); if(ok) return ; move(rev[i]); // 还原现场 } } int main(){ init(); while(scanf("%d",&a[0]) && a[0]){ for(int i=1; i<24; i++) a[i]=read(); ok = 0; if(is_final()) puts("No moves needed"); else{ for(maxd=1; ; maxd++){ dfs(0); if(ok) break; } } cout << a[6] << endl; // 最终的颜色 } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-35939.html

    最新回复(0)