青蛙跳跃对调位置游戏的穷举解决算法

  游戏在这里,让左边的青蛙和右边的青蛙对调位置。左边和右边各有三只青蛙,中心处有一个空位。每次可以跳一个青蛙,要么向前跳一格,要么跨过前方的青蛙跳一格,青蛙不能重叠,不能往回跳。

  下面是解决该问题的穷举算法实现,算法已扩展到左边有任意只青蛙、右边有任意只青蛙、中间有任意个空位的情形:

lr4.h

 1 #ifndef _LR4_H
 2 #define _LR4_H
 3 
 4 #ifdef __cplusplus
 5 extern "C" {
 6 #endif
 7 
 8 int Resolve(int left, int blank, int right, int **ppMaps, int **ppMeds, int *pCount);
 9 
10 #ifdef __cplusplus
11 };
12 #endif
13 
14 #endif

lr4.c

  1 #include <stdio.h>
  2 #include <memory.h>
  3 #include <malloc.h>
  4 
  5 typedef int BOOL;
  6 
  7 #define TRUE  1
  8 #define FALSE 0
  9 
 10 BOOL IsEqualMap(const int *pMap1, const int *pMap2, int total)
 11 {
 12     return memcmp(pMap1, pMap2, total * sizeof(int)) == 0;
 13 }
 14 
 15 void InitBeginTailMap(int left, int blank, int right, int *pBeginMap, int *pTailMap)
 16 {
 17     int index;
 18 
 19     pTailMap += left + blank + right - 1;
 20 
 21     for(index = 0; index < left; index += 1)
 22     {
 23         *pBeginMap++ = *pTailMap-- = -1;
 24     }
 25 
 26     for(index = 0; index < blank; index += 1)
 27     {
 28         *pBeginMap++ = *pTailMap-- = 0;
 29     }
 30 
 31     for(index = 0; index < right; index += 1)
 32     {
 33         *pBeginMap++ = *pTailMap-- = 1;
 34     }
 35 }
 36 
 37 BOOL GetNextMap(const int *pCurrentMap, int *pNextMap, int med, int total)
 38 {
 39     if(pCurrentMap[med] != 0)
 40     {
 41         int med1 = med - pCurrentMap[med];
 42         int med2 = med1 - pCurrentMap[med];
 43 
 44         memcpy(pNextMap, pCurrentMap, total * sizeof(int));
 45 
 46         if(pNextMap[med] == 1)
 47         {
 48             if(med1 >= 0 && pNextMap[med1] == 0)
 49             {
 50                 pNextMap[med1] = pNextMap[med];
 51                 pNextMap[med] = 0;
 52 
 53                 return TRUE;
 54             }
 55             else if(med2 >= 0 && pNextMap[med2] == 0)
 56             {
 57                 pNextMap[med2] = pNextMap[med];
 58                 pNextMap[med] = 0;
 59 
 60                 return TRUE;
 61             }
 62         }
 63         else
 64         {
 65             if(med1 < total && pNextMap[med1] == 0)
 66             {
 67                 pNextMap[med1] = pNextMap[med];
 68                 pNextMap[med] = 0;
 69 
 70                 return TRUE;
 71             }
 72             else if(med2 < total && pNextMap[med2] == 0)
 73             {
 74                 pNextMap[med2] = pNextMap[med];
 75                 pNextMap[med] = 0;
 76 
 77                 return TRUE;
 78             }
 79         }
 80     }
 81 
 82     return FALSE;
 83 }
 84 
 85 int Resolve(int left, int blank, int right, int **ppMaps, int **ppMeds, int *pCount)
 86 {
 87     BOOL result = FALSE;
 88     int total = left + blank + right;
 89     int *pEndMap = (int *)malloc(total * sizeof(int));
 90     int count = 0;
 91 
 92     *ppMaps = NULL;
 93     *ppMeds = NULL;
 94 
 95     *ppMaps = (int *)realloc(*ppMaps, (count + 1) * total * sizeof(int));
 96     *ppMeds = (int *)realloc(*ppMeds, (count + 1) * sizeof(int));
 97 
 98     if(pEndMap == NULL || *ppMaps == NULL || *ppMeds == NULL)
 99     {
100         return FALSE;
101     }
102 
103     InitBeginTailMap(left, blank, right, ppMaps[0], pEndMap);
104     **ppMeds = -1;
105     count = 1;
106 
107     while(TRUE)
108     {
109         if(count == 0)
110         {
111             break;
112         }
113 
114         if(IsEqualMap(*ppMaps + (count - 1) * total, pEndMap, total))
115         {
116             result = TRUE;
117             break;
118         }
119 
120         (*ppMeds)[count - 1] += 1;
121 
122         if((*ppMeds)[count - 1] >= total)
123         {
124             count -= 1;
125         }
126         else
127         {
128             *ppMaps = (int *)realloc(*ppMaps, (count + 1) * total * sizeof(int));
129             *ppMeds = (int *)realloc(*ppMeds, (count + 1) * sizeof(int));
130 
131             if(*ppMaps == NULL || *ppMeds == NULL)
132             {
133                 break;
134             }
135 
136             if(GetNextMap(*ppMaps + (count - 1) * total, *ppMaps + count * total, (*ppMeds)[count - 1], total))
137             {
138                 (*ppMeds)[count] = -1;
139 
140                 count += 1;
141             }
142         }
143     }
144 
145     if(!result)
146     {
147         if(*ppMaps != NULL)
148         {
149             free(*ppMaps);
150         }
151 
152         if(*ppMeds != NULL)
153         {
154             free(*ppMeds);
155         }
156     }
157 
158     *pCount = count;
159 
160     return result;
161 }

main.c

 

 1 #include <stdio.h>
 2 #include "lr4.h"
 3 
 4 int main()
 5 {
 6     int *pMaps, *pMeds, count;
 7     int left = 4;
 8     int blank = 2;
 9     int right = 4;
10 
11     if(Resolve(left, blank, right, &pMaps, &pMeds, &count))
12     {
13         int total = left + blank + right;
14         int index, index2;
15 
16         for(index = 0; index < count; index += 1)
17         {
18             if(index == 0)
19             {
20                 printf("初始状态局面:");
21             }
22             else
23             {
24                 printf("第%2d步后局面:", index);
25             }
26 
27             for(index2 = 0; index2 < total; index2 += 1)
28             {
29                 printf("%3d", pMaps[index * total + index2]);
30             }
31 
32             if(index != count - 1)
33             {
34                 printf(" 跳左起第%d个青蛙\n", pMeds[index] + 1);
35             }
36         }
37 
38         printf("\n");
39 
40         free(pMeds);
41         free(pMaps);
42     }
43 
44     return 0;
45 }

 

示例输出:

左右各三只青蛙,中间一个空位的情形:

初始状态局面: -1 -1 -1 0 1 1 1 跳左起第3个青蛙
第 1步后局面: -1 -1 0 -1 1 1 1 跳左起第5个青蛙
第 2步后局面: -1 -1 1 -1 0 1 1 跳左起第6个青蛙
第 3步后局面: -1 -1 1 -1 1 0 1 跳左起第4个青蛙
第 4步后局面: -1 -1 1 0 1 -1 1 跳左起第2个青蛙
第 5步后局面: -1 0 1 -1 1 -1 1 跳左起第1个青蛙
第 6步后局面: 0 -1 1 -1 1 -1 1 跳左起第3个青蛙
第 7步后局面: 1 -1 0 -1 1 -1 1 跳左起第5个青蛙
第 8步后局面: 1 -1 1 -1 0 -1 1 跳左起第7个青蛙
第 9步后局面: 1 -1 1 -1 1 -1 0 跳左起第6个青蛙
第10步后局面: 1 -1 1 -1 1 0 -1 跳左起第4个青蛙
第11步后局面: 1 -1 1 0 1 -1 -1 跳左起第2个青蛙
第12步后局面: 1 0 1 -1 1 -1 -1 跳左起第3个青蛙
第13步后局面: 1 1 0 -1 1 -1 -1 跳左起第5个青蛙
第14步后局面: 1 1 1 -1 0 -1 -1 跳左起第4个青蛙
第15步后局面: 1 1 1 0 -1 -1 -1

 

左右各四个青蛙,中间两个空位的情形:

初始状态局面: -1 -1 -1 -1 0 0 1 1 1 1 跳左起第3个青蛙
第 1步后局面: -1 -1 0 -1 -1 0 1 1 1 1 跳左起第1个青蛙
第 2步后局面: 0 -1 -1 -1 -1 0 1 1 1 1 跳左起第5个青蛙
第 3步后局面: 0 -1 -1 -1 0 -1 1 1 1 1 跳左起第7个青蛙
第 4步后局面: 0 -1 -1 -1 1 -1 0 1 1 1 跳左起第8个青蛙
第 5步后局面: 0 -1 -1 -1 1 -1 1 0 1 1 跳左起第6个青蛙
第 6步后局面: 0 -1 -1 -1 1 0 1 -1 1 1 跳左起第4个青蛙
第 7步后局面: 0 -1 -1 0 1 -1 1 -1 1 1 跳左起第3个青蛙
第 8步后局面: 0 -1 0 -1 1 -1 1 -1 1 1 跳左起第5个青蛙
第 9步后局面: 0 -1 1 -1 0 -1 1 -1 1 1 跳左起第3个青蛙
第10步后局面: 1 -1 0 -1 0 -1 1 -1 1 1 跳左起第2个青蛙
第11步后局面: 1 0 -1 -1 0 -1 1 -1 1 1 跳左起第7个青蛙
第12步后局面: 1 0 -1 -1 1 -1 0 -1 1 1 跳左起第9个青蛙
第13步后局面: 1 0 -1 -1 1 -1 1 -1 0 1 跳左起第10个青蛙
第14步后局面: 1 0 -1 -1 1 -1 1 -1 1 0 跳左起第8个青蛙
第15步后局面: 1 0 -1 -1 1 -1 1 0 1 -1 跳左起第6个青蛙
第16步后局面: 1 0 -1 -1 1 0 1 -1 1 -1 跳左起第4个青蛙
第17步后局面: 1 0 -1 0 1 -1 1 -1 1 -1 跳左起第3个青蛙
第18步后局面: 1 0 0 -1 1 -1 1 -1 1 -1 跳左起第5个青蛙
第19步后局面: 1 0 1 -1 0 -1 1 -1 1 -1 跳左起第3个青蛙
第20步后局面: 1 1 0 -1 0 -1 1 -1 1 -1 跳左起第7个青蛙
第21步后局面: 1 1 0 -1 1 -1 0 -1 1 -1 跳左起第5个青蛙
第22步后局面: 1 1 1 -1 0 -1 0 -1 1 -1 跳左起第4个青蛙
第23步后局面: 1 1 1 0 -1 -1 0 -1 1 -1 跳左起第9个青蛙
第24步后局面: 1 1 1 0 -1 -1 1 -1 0 -1 跳左起第8个青蛙
第25步后局面: 1 1 1 0 -1 -1 1 0 -1 -1 跳左起第6个青蛙
第26步后局面: 1 1 1 0 -1 0 1 -1 -1 -1 跳左起第5个青蛙
第27步后局面: 1 1 1 0 0 -1 1 -1 -1 -1 跳左起第7个青蛙
第28步后局面: 1 1 1 0 1 -1 0 -1 -1 -1 跳左起第5个青蛙
第29步后局面: 1 1 1 1 0 -1 0 -1 -1 -1 跳左起第6个青蛙
第30步后局面: 1 1 1 1 0 0 -1 -1 -1 -1

 

posted on 2013-03-04 20:46  Shilyx  阅读(983)  评论(0编辑  收藏  举报

导航