零件匹配题目:
现在,有若干个零件,需要你匹配
求所有能匹配的组合中,最大的组合长度T_max (T释义见图4),以及能匹配出??_max的组合个数n
例如:
有26个零件,分别是A-Z,其中能匹配的组合只有三组(A,B), (C,D), (E,F)
(A,B)匹配后,组合长度T=5
(C,D)匹配后,组合长度T=3
(E,F)匹配后,组合长度T=5
则 ??max=5, ??=2
输入
第一行一个整数t, 表示有t组测试数据, 1≤??≤50
每组第一行一个整数m,表示零件个数 , 0<??≤100,000
下面有m行,每行17个整数,表示零件数据
其中第一个表示零件本体长度L, 0<??≤100,000,000
剩余16个表示零件头矩阵,按从左到右,从上到下顺序排列,如下图。
对矩阵中每个元素??, 有 0≤??≤2
输出
最大的组合长度??T_max ,能匹配出??_max的组合个数n。
用空格分开,回车结束
待完善
参考代码:
1 #include <stdio.h> 2 #include <windows.h> 3 #define MAXPAT 43046721 4 #define MAXNUM 100005 5 int T, N, ans, index = MAXNUM - 1, maxlen; 6 int exp[16] = { 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907 }; 7 int key[MAXNUM];//优化 8 struct Node{//存放最小的pat 9 int len, num; 10 int data[16], top; 11 Node *next; 12 }NIL, node[MAXNUM], *map[MAXPAT]; 13 int v[4][16] = { 14 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, 15 { 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12 }, 16 { 12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3 }, 17 { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 } 18 }; 19 int findVal(int a[16]){ 20 int ret = MAXPAT + 1, temp; 21 for (int i = 0; i < 4; ++i){ 22 temp = 0; 23 for (int j = 0; j < 16; ++j) 24 temp = temp + a[j] * exp[v[i][j]]; 25 if (temp < ret)ret = temp; 26 } 27 return ret; 28 } 29 void getMaxLen(){ 30 maxlen = ans = 0; 31 int a[16]; 32 Node *lover; 33 for (int i = 0; i <= index; ++i){ 34 int pos = key[i]; 35 if (map[pos]->len < 0)continue; 36 for (int j = 0; j < 4; ++j) 37 for (int k = 0; k < 4; ++k) 38 a[j * 4 + k] = map[pos]->top - map[pos]->data[j * 4 + 3 - k]; 39 int pat = findVal(a); 40 if (map[pat]->len < 0){ 41 map[pos] = &NIL; 42 continue; 43 } 44 if (pat < pos)continue; 45 if(pat == pos){ 46 if(map[pos]->num > 1){ 47 if(map[pos]->len * 2 + map[pos]->top > maxlen){ 48 maxlen = map[pos]->len * 2 + map[pos]->top; 49 ans = map[pos]->num / 2; 50 } 51 else if(map[pos]->len * 2 + map[pos]->top == maxlen) 52 ans += map[pos]->num / 2; 53 map[pos] = &NIL; 54 continue; 55 } 56 else lover = map[pos]->next; 57 } 58 else{ 59 lover = map[pat]; 60 map[pat] = &NIL; 61 } 62 if(map[pos]->len + lover->len + map[pos]->top > maxlen){ 63 maxlen = map[pos]->len + lover->len + map[pos]->top; 64 ans = map[pos]->num < lover->num ? map[pos]->num : lover->num; 65 } 66 else if(map[pos]->len + lover->len + map[pos]->top == maxlen) 67 ans += map[pos]->num < lover->num ? map[pos]->num : lover->num; 68 map[pos] = &NIL; 69 } 70 } 71 int main(void){ 72 freopen("input.txt", "r", stdin); 73 freopen("result.txt", "w", stdout); 74 scanf("%d", &T); 75 NIL.len = -1; 76 NIL.next = &NIL; 77 for (int i = 0; i < MAXPAT; ++i)map[i] = &NIL; 78 DWORD start_time = GetTickCount(); 79 for (int tc = 1; tc <= T; ++tc){ 80 index = -1; 81 scanf("%d", &N); 82 for (int i = 0; i < N; ++i){ 83 ++index; 84 scanf("%d", &node[index].len); 85 node[index].top = 0; 86 node[index].num = 1; 87 for (int j = 0; j < 16; ++j){ 88 scanf("%d", &node[index].data[j]); 89 if (node[index].data[j] > node[index].top) 90 node[index].top = node[index].data[j]; 91 } 92 int pat = findVal(node[index].data); 93 key[index] = pat; 94 if (map[pat]->len < node[index].len){//应该插入到头部 95 node[index].next = map[pat]; 96 map[pat] = &node[index]; 97 continue; 98 } 99 Node *cur = map[pat]; 100 while (true){ 101 if (cur->len == node[index].len){ 102 ++cur->num; 103 --index; 104 break; 105 } 106 if (cur->next->len < node[index].len){ 107 node[index].next = cur->next; 108 cur->next = &node[index]; 109 break; 110 } 111 cur = cur->next; 112 } 113 } 114 getMaxLen(); 115 printf("#%d %d %d\\n", tc, maxlen, ans); 116 } 117 DWORD end_time = GetTickCount(); 118 printf("%d ms\\n", end_time - start_time); 119 return 0; 120 }