• 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

  • 相关阅读:
    ubuntu 通过命令将数据复制到u盘
    项目感言--功能的模块化
    java 中变量的存储与引用
    java 基础拾漏
    自动完成--autoComplete插件(2)
    自动完成--autoComplete插件
    Linux查看端口
    Linux查看系统信息
    js splice方法
    slice、substring、substr
  • 原文地址:https://www.cnblogs.com/siyuan/p/2029666.html
Copyright © 2020-2023  润新知