您的位置:首页 > 其它

Section 1.4,The Clocks

2011-04-26 19:28 423 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: