zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    hdu 5723 Abandoned country 最小生成树 期望
    OpenJ_POJ C16G Challenge Your Template 迪杰斯特拉
    OpenJ_POJ C16D Extracurricular Sports 打表找规律
    OpenJ_POJ C16B Robot Game 打表找规律
    CCCC 成都信息工程大学游记
    UVALive 6893 The Big Painting hash
    UVALive 6889 City Park 并查集
    UVALive 6888 Ricochet Robots bfs
    UVALive 6886 Golf Bot FFT
    UVALive 6885 Flowery Trails 最短路
  • 原文地址:https://www.cnblogs.com/siyuan/p/2029666.html
Copyright © 2011-2022 走看看