题目链接:
https://vjudge.net/problem/UVA-1343
题意:
数字1,2,3都有八个,求出最少的旋转次数使得图形中间八个数相同。
旋转规则:对于每一长行或每一长列,每次旋转就是将数据向头的位置移动一位,头上的数放置到尾部。若次数相同,则找出字典序最小旋转次序。
输入是从上到下,从左向右,注意方向
题解:
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 1e5+10; 17 18 int maxd,ok,a[50]; 19 char ans[maxn]; 20 int line[8][7] = { 21 {0,2,6,11,15,20,22}, 22 {1,3,8,12,17,21,23}, 23 {10,9,8,7,6,5,4}, 24 {19,18,17,16,15,14,13} 25 }; 26 27 int rev[8] = {5,4,7,6,1,0,3,2}; // 通过A,B,C,D,反推其他方向。指向反向,用来还原现场。 28 int final[8] = {6,7,8,11,12,15,16,17}; // 最后答案要求的点 29 30 void init(){ // 反推方向 31 for(int i=4; i<8; i++) 32 for(int j=0; j<=6; j++) 33 line[i][j] = line[rev[i]][6-j]; 34 } 35 36 bool is_final(){ 37 int k = a[final[0]]; 38 for(int i=1; i<8; i++) 39 if(a[final[i]]!=k) return false; 40 return true; 41 } 42 43 void move(int k){ 44 int tmp = a[line[k][0]]; 45 for(int i=1; i<7; i++) 46 a[line[k][i-1]] = a[line[k][i]]; 47 a[line[k][6]] = tmp; 48 } 49 50 int diff(int x){ 51 int cnt = 0; 52 for(int i=0; i<8; i++) 53 if(x != a[final[i]]) 54 cnt++; 55 return cnt; 56 } 57 58 int h(){ //估值函数 59 return min(min(diff(1),diff(2)),diff(3)); 60 } 61 62 void dfs(int cur){ 63 if(is_final()){ 64 ans[cur] = '