额,debug 一步步跟进,同时查看所有变量
草稿纸上画一下变化。
程序代码:
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX 128
#define MIN(x, y) ((x) < (y)) ? (x) : (y)
typedef struct __tag_status
{
int s, m, n, step;
} Status;
// 判断两种状态是否相等
bool EquelStatus(Status *from, Status *to)
{
return from->s == to->s && from->m == to->m && from->n == to->n;
}
typedef struct __tag_queue
{
int front, rear;
Status data[MAX];
} Queue;
// 入队列
void EnQueue(Queue *queue, Status *status)
{
if (queue->rear == MAX) exit(EXIT_FAILURE);
queue->data[queue->rear++] = *status;
}
// 出队列
void DeQueue(Queue *queue, Status *status)
{
*status = queue->data[queue->front++];
}
// 队列空
bool EmptyQueue(Queue *queue)
{
return queue->front >= queue->rear;
}
// 队列中是否存在这个状态
bool StatusInQueue(Queue *queue, Status *status)
{
for (int i = 0; i < queue->rear; ++i)
{
if (EquelStatus(&queue->data[i], status)) return true;
}
return false;
}
typedef enum __tag_action
{
S_TO_M, S_TO_N, M_TO_S, M_TO_N, N_TO_S, N_TO_M
} Action;
// 当前状态是否可以执行动作
bool CanMove(Status *status, Action action, Status *max)
{
switch (action)
{
case S_TO_M: return status->s > 0 && status->m < max->m;
case S_TO_N: return status->s > 0 && status->n < max->n;
case M_TO_S: return status->m > 0 && status->s < max->s;
case M_TO_N: return status->m > 0 && status->n < max->n;
case N_TO_S: return status->n > 0 && status->s < max->s;
case N_TO_M: return status->n > 0 && status->m < max->m;
}
return false;
}
// 获取执行action动作后的下一状态
Status Move(Status *status, Action action, Status *max)
{
Status next = *status;
switch (action)
{
case S_TO_M:
next.m = MIN(max->m, status->s + status->m);
next.s = status->s + status->m - next.m;
break;
case S_TO_N:
next.n = MIN(max->n, status->s + status->n);
next.s = status->s + status->n - next.n;
break;
case M_TO_S:
next.s = MIN(max->s, status->m + status->s);
next.m = status->m + status->s - next.s;
break;
case M_TO_N:
next.n = MIN(max->n, status->m + status->n);
next.m = status->m + status->n - next.n;
break;
case N_TO_S:
next.s = MIN(max->s, status->n + status->s);
next.n = status->n + status->s - next.s;
break;
case N_TO_M:
next.m = MIN(max->m, status->n + status->m);
next.n = status->n + status->m - next.m;
break;
}
next.step += 1;
return next;
}
// 成功结束标志
bool EndStatus(Status *status, int s)
{
if (s % 2) return false;
int ans = 0;
ans += status->s == s / 2;
ans += status->m == s / 2;
ans += status->n == s / 2;
return ans >= 2;
}
// 广搜
void bfs(int s, int m, int n)
{
Queue queue = {0};
Status max = {INT_MAX, m, n}, beg = {.s = s};
EnQueue(&queue, &beg);
while (!EmptyQueue(&queue))
{
Status now;
DeQueue(&queue, &now);
// 判断是否为终止状态
if (EndStatus(&now, s))
{
printf("%d\n", now.step);
return;
}
// 将下一状态入队列
for (Action action = S_TO_M; action <= N_TO_M; ++action)
{
if (CanMove(&now, action, &max))
{
Status next = Move(&now, action, &max);
if (!StatusInQueue(&queue, &next))
{
EnQueue(&queue, &next);
}
}
}
}
printf("NO\n");
}
int main(int argc, char *argv[])
{
bfs(7, 4, 3);
bfs(4, 1, 3);
return 0;
}
[此贴子已经被作者于2016-12-21 11:39编辑过]