Section 1.4,Mother's Milk
1题目描述
http://ace.delos.com/usacoprob2?a=bDgbfJDh5Pw&S=milk3
2解题思路
广度优先搜索,具体如下:
1)搜索状态保存在一个队列中结构体queue中,已经存在的状态保存在一个二维数组statelist中
2)在一个二重循环中产生下一个状态
3)加入队列的条件是下一状态在statelist中不存在。
3代码
/*
ID: wangsiy1
LANG: C
TASK: milk3
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define QLEN 10000
#define LISTLEN 1000
#define DEBUG 0
/* bucket行为队列下标,列为三个筒 */
typedef struct {
int bucket[QLEN][3];
int head, tail;
} queue;
int capacity[3];
void printg(queue *q)
{
int i, j;
for(i=q->head; i<q->tail; i++) {
printf("bucket[%d]:\n", i);
for(j=0; j<3; j++)
printf("%d ", q->bucket[i][j]);
}
printf("\n");
}
void init(queue *q)
{
q->head = 0;
q->tail = 0;
}
int empty(queue *q)
{
if(q->head==q->tail)
return 1;
else
return 0;
}
int dequeue(queue *q, int *state)
{
int i;
if(empty(q))
return 0;
else {
for(i=0; i<3; i++)
state[i] = q->bucket[q->head][i];
q->head = (q->head + 1) % QLEN;
return 1;
}
}
int enqueue (queue *q, int *state)
{
int i;
if((q->tail+1)%QLEN == q->head)
return 0;
else {
for(i=0; i<3; i++)
q->bucket[q->tail][i] = state[i];
q->tail = (q->tail+1) % QLEN;
return 1;
}
}
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int existresult(int *result, int h, int m)
{
int i;
for(i=0; i<m; i++)
if(result[i]==h)
return 1;
return 0;
}
int insertlist(int statelist[][3], int *listlen, int *state)
{
int i;
for(i=0; i<3; i++)
statelist[*listlen][i] = state[i];
++(*listlen);
}
int isinlist(int statelist[][3], int listlen, int *state)
{
int i, j, f;
for(i=0; i<listlen; i++) {
f=1;
for(j=0; j<3; j++) {
if(statelist[i][j] != state[j]) {
f=0;
break;
}
}
if(f==1)
return 1;
}
return 0;
}
main ()
{
queue *q;
int state[3], i, result[1000], resultlen, j, nxtstate[3];
int statelist[LISTLEN][3], listlen=0;
FILE *fin = fopen ("milk3.in", "r");
FILE *fout = fopen ("milk3.out", "w");
q = (queue *) malloc(sizeof(queue));
init(q);
for(i=0; i<3; i++)
fscanf(fin, "%d", capacity+i);
state[0] = 0;
state[1] = 0;
state[2] = capacity[2];
enqueue(q, state);
result[0] = state[2];
resultlen=1;
insertlist(statelist, &listlen, state);
while(!empty(q)) {
if(!dequeue(q, state)) {
printf("empty queue, cannot dequeue.\n");
exit(0);
}
for(i=0; i<3; i++) {
if(state[i]!=0) {
for(j=0; j<3; j++) {
if(i!=j && state[j]<capacity[j]) {
nxtstate[0] = state[0];
nxtstate[1] = state[1];
nxtstate[2] = state[2];
if(capacity[j]-state[j]>=state[i]) {
nxtstate[j] = state[j] + state[i];
nxtstate[i] = 0;
} /* if(capacity[j]-state[j]>=state[i]) */
else {
nxtstate[j] = capacity[j];
nxtstate[i] = state[i] - capacity[j] + state[j];
}
if(!isinlist(statelist, listlen, nxtstate)) {
#if DEBUG
printf("%d %d %d\n", nxtstate[0], nxtstate[1], nxtstate[2]);
#endif
if(nxtstate[0]==0 &&
!existresult(result, nxtstate[2], resultlen))
result[resultlen++] = nxtstate[2];
enqueue(q, nxtstate);
insertlist(statelist, &listlen, nxtstate);
}
} /* if(i!=j && state[j]<capacity[j]) */
} /* for(j=0; j<3; j++) */
} /* if(state[i]!=0) */
} /* for(i=0; i<3; i++) */
}
qsort(result, resultlen, sizeof(int), cmp);
for(i=0; i<resultlen; i++) {
fprintf(fout, "%d", result[i]);
if(i!=resultlen-1)
fprintf(fout, " ");
}
fprintf(fout, "\n");
exit (0);
}