1. 题目描述
有个#字型的条带,可以从横线或竖线进行循环移动,求通过各种移动最终使中心的8个字符全等的长度最短并相同长度字典序最小的操作序列。
2. 基本思路
24个数据,8种移动方式,数据量很小了,所以基本怎么玩儿都可以。
需要注意的是因为横线竖线间有交点,所以每个条带的数据可能都是变化的。
采用IDA*算法可解。
所谓IDA*,就是不断对所求操作需要长度进行增加,然后不断当前长度是否存在可行的操作序列。
判断是否存在可行操作序列的方法是深搜,这里需要注意去除先移动A紧接着移动F的类似情况。
H函数的基本想法很简单,即判断中心8个字符的最少改变几个就可以满足条件。
3. 代码
1 /* 1667 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 const int INF = 0x3f3f3f3f; 44 const int maxl = 300; 45 int op[maxl]; 46 int a[24]; 47 int pos[8][7] = { 48 {0, 2, 6, 11, 15, 20, 22}, 49 {1, 3, 8, 12, 17, 21, 23}, 50 {10, 9, 8, 7, 6, 5, 4}, 51 {19, 18, 17, 16, 15, 14, 13} 52 }; 53 int eight[8] = { 54 6, 7, 8, 11, 12, 15, 16, 17 55 }; 56 int mirror[8] = { 57 5, 4, 7, 6, 1, 0, 3, 2 58 }; 59 bool flag; 60 int v; 61 62 void Init() { 63 rep(i, 0, 4) { 64 int j = mirror[i]; 65 memcpy(pos[j], pos[i], sizeof(pos[j])); 66 reverse(pos[j], pos[j]+7); 67 } 68 } 69 70 void Rotate(int *a, int d) { 71 int tmp = a[pos[d][0]]; 72 rep(i, 1, 7) 73 a[pos[d][i-1]] = a[pos[d][i]]; 74 a[pos[d][6]] = tmp; 75 } 76 77 int H(int *a) { 78 int c[4]; 79 80 c[1] = c[2] = c[3] = 0; 81 rep(i, 0, 8) 82 ++c[a[eight[i]]]; 83 84 return 8 - max(c[1], max(c[2], c[3])); 85 } 86 87 void dfs(int *a, int dep, int fa) { 88 int mn = H(a); 89 90 if (dep < mn) 91 return ; 92 93 if (dep == 0) { 94 if (mn == 0) { 95 flag = true; 96 v = a[eight[0]]; 97 } 98 return ; 99 } 100 101 int b[24]; 102 103 rep(i, 0, 8) { 104 if (mirror[i] == fa) 105 continue; 106 op[dep] = i; 107 memcpy(b, a, sizeof(b)); 108 Rotate(b, i); 109 dfs(b, dep-1, i); 110 if (flag) return ; 111 } 112 } 113 114 void solve() { 115 int mn = H(a); 116 117 if (mn == 0) { 118 printf("No moves needed %d ", a[eight[0]]); 119 return ; 120 } 121 122 flag = false; 123 for (int l=mn; ; ++l) { 124 dfs(a, l, -1); 125 if (flag) { 126 per(i, 1, l+1) { 127 putchar('A'+op[i]); 128 } 129 printf(" %d ", v); 130 break; 131 } 132 } 133 } 134 135 int main() { 136 ios::sync_with_stdio(false); 137 #ifndef ONLINE_JUDGE 138 freopen("data.in", "r", stdin); 139 freopen("data.out", "w", stdout); 140 #endif 141 142 Init(); 143 while (scanf("%d", &a[0])!=EOF && a[0]) { 144 rep(i, 1, 24) 145 scanf("%d", &a[i]); 146 solve(); 147 } 148 149 #ifndef ONLINE_JUDGE 150 printf("time = %d. ", (int)clock()); 151 #endif 152 153 return 0; 154 }
4. 数据生成器。
/* 2 3 2 2 1 1 3 1 3 2 2 1 2 2 2 3 3 2 3 1 2 2 2 2 2 3 2 1 2 1 1 2 1 2 2 3 2 2 2 2 2 2 1 3 3 2 2 2 1 1 3 1 3 3 1 3 3 3 1 3 2 1 2 2 1 3 3 3 1 3 3 3 1 2 1 1 1 2 1 2 1 3 1 2 1 2 2 1 1 1 1 1 2 1 3 1 3 2 3 3 3 2 3 3 1 2 3 3 3 1 3 1 2 1 3 3 2 3 2 3 2 2 3 2 3 3 2 1 3 2 2 3 1 2 2 2 2 2 1 2 1 2 3 2 3 2 1 1 3 3 3 1 2 3 3 3 2 3 1 3 3 3 3 3 1 1 3 3 3 2 3 3 3 2 2 1 1 3 1 3 3 3 2 3 3 3 1 3 3 3 3 2 1 3 2 1 1 3 1 1 1 3 3 1 1 1 3 3 3 2 1 1 2 1 1 2 1 1 3 3 2 3 1 3 2 3 2 1 3 1 2 2 2 1 1 2 2 2 3 2 0 */ /* AABDDHA 2 BFFF 2 BBGGH 3 AGHBH 1 GBGF 3 ABBHHF 2 BCCEC 3 BHA 3 EGG 1 ADHBBH 2 */
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 10 10 bound = 10**5 11 # fout.write("%d " % (t)) 12 for tt in xrange(t): 13 n1 = randint(10, 15) 14 token = randint(1, 3) 15 L = [token for i in xrange(n1)] 16 op = range(1, 4) 17 op.remove(token) 18 for i in xrange(24-n1): 19 idx = randint(0, 1) 20 x = op[idx] 21 L.append(x) 22 shuffle(L) 23 fout.write(" ".join(map(str, L)) + " ") 24 fout.write("0 ") 25 26 def MovDataIn(): 27 desFileName = "F:eclipse_prjworkspacehdojdata.in" 28 shutil.copyfile("data.in", desFileName) 29 30 31 if __name__ == "__main__": 32 GenDataIn() 33 MovDataIn()