王思源

 

Section 1.4,The Clocks

1题目描述

英文: http://ace.delos.com/usacoprob2?a=2dcMjFnNl7S&S=clocks

中文翻译: http://www.nocow.cn/index.php/Translate:USACO/clocks

2深度优先搜索解法

2.1 思路:用二进制的三位保存一个时钟的状态。低两位表示四种状态,第三位用作进位,每次操作后置零[1][2]

2.2 代码:

/*
ID: wangsiy1
LANG: C
TASK: clocks
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>

#define DEBUG 1

/* 移动方法编号是way的下标加一 */
int way[9] = {
/*00A00B00C00D00E00F00G00H00I */
0b001001000001001000000000000,
/* 1 */
0b001001001000000000000000000,
/* 2 */
0b000001001000001001000000000,
/* 3 */
0b001000000001000000001000000,
/* 4 */
0b000001000001001001000001000,
/* 5 */
0b000000001000000001000000001,
/* 6 */
0b000000000001001000001001000,
/* 7 */
0b000000000000000000001001001,
/* 8 */
0b000000000000001001000001001,
/* 9 */
};

int afteradd = 0b00000011011011011011011011011011;

int cantakethis(int *path, int i, int depth)
{
int m, r=0;
for(m=0; m<depth; m++) {
if(path[m]==i)
++r;
}
if (r>=3) return 0;
else return 1;
}

void printresult(int *path, int depth)
{
int i;
FILE
*fout = fopen ("clocks.out", "w");
for(i=0; i<depth; i++) {
fprintf(fout,
"%d", path[i]);
if(i==depth-1)
fprintf(fout,
"\n");
else
fprintf(fout,
" ");
}
}

/* state初始为0 */
void readdata(FILE *fin, int *state)
{
int c, i;
for(i=0; i<9; i++) {
fscanf(fin,
"%d", &c);
(
*state) <<= 3;
if(c==12)
c
= 0;
else if (c==3)
c
= 1;
else if (c==6)
c
= 2;
else if (c==9)
c
= 3;
*state |= c;
}
}


void dfs(int depth, int state, int *path)
{
int i, firstway, tmpstate;
if(state==0) {
printresult(path, depth);
}
else {
if(depth > 0)
firstway
= path[depth-1];
else
firstway
= 1;
/* i 方法编号,既下标加一 */
for(i=firstway; i<=9; i++) {
if (cantakethis(path, i, depth)) {
tmpstate
= state;
state
+= way[i-1];
state
&= afteradd;
path[depth]
= i;
/* printresult(path, depth); */
dfs(depth
+1, state, path);
state
= tmpstate;
}
}
}
}

main ()
{
/* path[]记录方法步骤,depth为递归深度,同时为depth的最后一个元素下标 */
int state=0, path[27], depth=0;
char s[32];
FILE
*fin = fopen ("clocks.in", "r");


readdata(fin,
&state);
/* printf("%d\n", state); */
dfs(
0, state, path);
exit (
0);
}

2.3 执行结果

Executing...
   Test 1: TEST OK [0.027 secs, 1972 KB]
   Test 2: TEST OK [0.027 secs, 1972 KB]
   Test 3: TEST OK [0.027 secs, 1972 KB]
   Test 4: TEST OK [0.027 secs, 1972 KB]
   Test 5: TEST OK [0.027 secs, 1972 KB]
   Test 6: TEST OK [0.027 secs, 1972 KB]
   Test 7: TEST OK [0.027 secs, 1972 KB]
   Test 8: TEST OK [0.027 secs, 1972 KB]
   Test 9: TEST OK [0.027 secs, 1972 KB]

3广度优先搜索解法

3.1广搜的队列最大长度为 4^9=262144 [1]

3.2代码

/*
ID: wangsiy1
LANG: C
TASK: clocks
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>

#define DEBUG 0
#define QLEN 262144

typedef
struct {
int state;
char path[27], len;
} clock;

/* 移动方法编号是way的下标加一 */
int way[9] = {
/*00A00B00C00D00E00F00G00H00I */
0b001001000001001000000000000,
/* 1 */
0b001001001000000000000000000,
/* 2 */
0b000001001000001001000000000,
/* 3 */
0b001000000001000000001000000,
/* 4 */
0b000001000001001001000001000,
/* 5 */
0b000000001000000001000000001,
/* 6 */
0b000000000001001000001001000,
/* 7 */
0b000000000000000000001001001,
/* 8 */
0b000000000000001001000001001,
/* 9 */
};

int afteradd = 0b00000011011011011011011011011011;

int cantakethis(clock *t, int i)
{
int m, r=0, depth = t->len;
for(m=0; m<depth; m++) {
if(t->path[m]==i)
++r;
}
if (r>=3) return 0;
else return 1;
}

void printresult(clock *t)
{
int i, len;
FILE
*fout = fopen ("clocks.out", "w");
len
= t->len;

for(i=0; i<len; i++) {
fprintf(fout,
"%hd", t->path[i]);
if(i==len-1)
fprintf(fout,
"\n");
else
fprintf(fout,
" ");
}
}

/* state初始为0 */
void readdata(FILE *fin, int *state)
{
int c, i;
for(i=0; i<9; i++) {
fscanf(fin,
"%d", &c);
(
*state) <<= 3;
if(c==12)
c
= 0;
else if (c==3)
c
= 1;
else if (c==6)
c
= 2;
else if (c==9)
c
= 3;
*state |= c;
}
}

void cpyclock(clock *from, clock *to)
{
int i;
to
->state = from->state;
to
->len = from->len;
for(i=0; i<from->len; i++)
to
->path[i] = from->path[i];
}

void dequeue(clock *queue, clock *tmp, int *head)
{
cpyclock(queue
+*head, tmp);
(
*head) = (++(*head)) % QLEN;
}

void enqueue(clock *queue, clock *tmp2, int *tail)
{
cpyclock(tmp2, queue
+*tail);
*tail = (++(*tail)) % QLEN;
}

void bfs(int state)
{
int head, tail, len, startway, i, j ;
clock queue[QLEN],
*tmp, *tmp2;
tmp
= (clock *) malloc (sizeof(clock));
tmp2
= (clock *) malloc (sizeof(clock));

queue[
0].state=state;
queue[
9].len = 0;
head
= 0;
tail
= 1;

while(head != tail) {
dequeue(queue, tmp,
&head);
if(tmp->state == 0) {
printresult(tmp);
return;
}
if(tmp->len>0)
startway
= tmp->path[tmp->len-1];
else
startway
= 1;
for(i=startway; i<=9; i++) {
if (cantakethis(tmp, i)) {
tmp2
->state = tmp->state + way[i-1];
tmp2
->state &= afteradd;
tmp2
->len = tmp->len + 1;
for(j=0; j<= tmp->len; j++)
tmp2
->path[j] = tmp->path[j];
tmp2
->path[tmp2->len - 1] = i;
#if DEBUG
/* printf("state: %d", tmp2->state); */
/* printf("path:"); */
/* printresult(tmp2); */
printf(
"len :%d\n", tmp2->len);
#endif
if(tmp2->state == 0) {
printresult(tmp2);
return;
}
else
enqueue(queue, tmp2,
&tail);
}
}
}
}
main ()
{
/* times操作次数 */
int state=0, path[27], times=0;
char s[32];
FILE
*fin = fopen ("clocks.in", "r");


readdata(fin,
&state);
/* printf("%d\n", state); */
bfs(state);
exit (
0);
}

3.3执行结果

Executing...
   Test 1: TEST OK [0.000 secs, 10044 KB]
   Test 2: TEST OK [0.000 secs, 10040 KB]
   Test 3: TEST OK [0.000 secs, 10036 KB]
   Test 4: TEST OK [0.000 secs, 10044 KB]
   Test 5: TEST OK [0.000 secs, 10040 KB]
   Test 6: TEST OK [0.054 secs, 10040 KB]
   Test 7: TEST OK [0.054 secs, 10040 KB]
   Test 8: TEST OK [0.054 secs, 10044 KB]
   Test 9: TEST OK [0.054 secs, 10044 KB]

参考文献:

 [1] http://www.nocow.cn/index.php/USACO/clocks

 [2] http://blog.csdn.net/pennyshe/archive/2011/02/27/6211780.aspx

posted on 2011-04-26 19:28  王思源  阅读(306)  评论(0编辑  收藏  举报

导航