zoukankan      html  css  js  c++  java
  • 蚂蚁和木杆问题

    最巧妙的方法是把两只蚂蚁相遇之后看出互相“穿透”。下面是老老实实的计算方法,呵呵。

    /*
     *    题目:有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。
     *    木杆很细,不能同时通过一只蚂蚁。开始时,蚂蚁的头朝左还是朝右是任意的
     *    它们只会朝前走或调头,但不会后退。
     *    当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。
     *    编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。
     
    */


    /*
     *              1         2          
     *    0123456789012345678901234567
     *       +   +   +     +     +
     *    ---+---+---+-----+-----+----
     *
     *    从左至右构成链表,从左端开始检查相邻蚂蚁是否相遇,是否需要移动(相距1cm时无需移动,仅改变方向)
     *    到达两端后从链表中删除
     *
     
    */


    #include 
    <stdio.h>
    #include 
    <stdlib.h>

    #define ALL 1

    #if ALL
    #define DETAIL 0
    #else
    #define DETAIL 1
    #endif

    #define ANT_NUM 5
    #define LENGTH 27

    #define LEFT -1
    #define RIGHT 1

    typedef 
    struct ant_struct {
        
    struct ant_struct *    left;    // nearly ant on the left
        struct ant_struct *    right;    // nearly ant on the right
        int                    index;
        
    int                    pos;    // current position, from 0 to n
        int                    dir;    // which direction, left or right
        int                    time;    // elapsed time
    }
     ant;

    void print_state( ant* s )
    {
        ant
    * p;

        p 
    = s->right;
        
    while ( p ) {
            printf(
    "(%d) postion: %2d direction: %s\n", p->index, p->pos,
                    (p
    ->dir==LEFT)?"left":((p->dir==RIGHT)?"right":"Bad direction"));
            p 
    = p->right;
        }

    }


    void set_direction( ant* head, int dir )
    {
        ant
    * p = head->right;

        
    while ( p ) {
            
    if ( dir % 2 )
                p
    ->dir = RIGHT;
            
    else
                p
    ->dir = LEFT;
            dir 
    >>= 1;
            p 
    = p->right;
        }

    }


    ant
    * init_state( int* pos, int dir, int ant_num )
    {
        ant
    * head;
        ant
    * p;
        ant
    * q;
        
        
    if ( (head = (ant *)malloc( sizeof(ant))) == NULL )
            exit(
    1);

        head
    ->pos = 0;
        head
    ->dir = 0;
        head
    ->left = NULL;
        head
    ->right = NULL;

        q 
    = head;

        
    for ( int i = 0; i < ant_num; i++ ) {
            
    if ( (p = (ant *)malloc( sizeof(ant))) == NULL )
                exit(
    1);

            p
    ->index    = i + 1;
            p
    ->pos        = pos[i];
            p
    ->time        = 0;

            p
    ->left        = q;
            q
    ->right    = p;
            p
    ->right    = NULL;

            q 
    = q->right;
        }

        set_direction( head, dir );

        
    return head;
    }


    void turn_round( ant* p )
    {
        p
    ->dir = -(p->dir);
    }


    bool ismoved( ant* a, ant* b)
    {
        
    if ( a == NULL )
            exit(
    1);
        
    if ( b == NULL ) {
            
    return false;
        }


        
    /*
         *    if there are 1 CM between a and b, they will meet and turn round 
         *    and return to the initial position in the 1 second.
         *    if there are 0, they have meet and turn round now.
         *    otherwise they will go along their direction
         
    */

        
    if ( a->dir == RIGHT && b->dir == LEFT ) {
            
    /*    meet and change its direction    */
            
    if ( b->pos - a->pos == 1 ) {
                turn_round( a );
                turn_round( b );

                
    return true;
            }

            
    else if( b->pos - a->pos == 0 ) {
                turn_round( a );
                turn_round( b );

                
    return false;
            }

        }


        
    return false;
    }


    void moveall( ant* head )
    {
        ant
    * p = head->right;

        
    while ( p ) {
            
    if ( ismoved( p, p->right ) == false ) {
                
    /*    move towards its direction */
                p
    ->pos += p->dir;
                p
    ->time++;

                
    /*    check whether it has gone out    */
                
    if ( p->pos == 0 || p->pos == LENGTH ) {
                    
    /*    delete the ant    */
    #if DETAIL
                    printf(
    "(%d) ant goes out at %d\n", p->index, p->time);
    #endif
                    
    /*    
                     *    if p is not at the end of list, the right node
                     *    point to the left node.
                     *    
    */

                    
    if ( p->right ) {
                        
    /*    remove the ant at the begin of list    */
                        p
    ->right->left = p->left;
                        p
    ->left->right = p->right;
                        free( p );
                        p 
    = head;
                    }

                    
    else {
                        
    /* reach the end of list, remove the ant */
                        p
    ->left->right = p->right;
                        free( p );
                        
    break;
                    }

                }

            }


            
    /*    check next ant    */
            p 
    = p->right;
        }

    }


    /*    one possibility    */
    int process( int* pos, int dir, int ant_num )
    {
        ant
    * s;
        
    int time = 1;

        s 
    = init_state( pos, dir, ant_num );

        
    /* keep moving util no ants    */
        
    while ( s->right ) {
            
    /* move all ants in a second    */
            moveall( s );
    #if DETAIL
            printf(
    "\ntime:%d\n", time);
            print_state( s );
    #endif
            time
    ++;
        }


        printf(
    "total time:%d\n", time);

        
    return time;
    }


    int main( void )
    {
        
    int pos[ANT_NUM] = 37111723 };
        
    int ant_num = ANT_NUM;
        
    int max = 0;
        
    int min = 10000;
        
    int now;
        
    int possibility = (1<<ANT_NUM) - 1;

    #if ALL
        
    while ( possibility >= 0 ) {

            now 
    = process( pos, possibility, ant_num );
            
    if ( now < min ) min = now;
            
    if ( now > max ) max = now;
            printf(
    "----possibility:%2d  max:%2d  min:%2d----\n\n", possibility, max, min);

            possibility
    --;
        }


        printf(
    "max time:%d, min time:%d\n", max, min);
    #else
        process( pos, 
    4, ant_num );
    #endif

        
    return 0;
    }


  • 相关阅读:
    DOM、Window对象操作
    JavaScript基础
    关于样式表的两个练习
    css样式表
    表单
    HTML的格式、内容容器、表格标签
    C#部分的总结
    Android自定义View之音频条形图
    String, StringBuilder, StringBuffer问题
    详解Java中ArrayList、Vector、LinkedList三者的异同点(转)
  • 原文地址:https://www.cnblogs.com/faraway/p/1243125.html
Copyright © 2011-2022 走看看