N 人报数,最后只剩一人问题

/**
* 现有N个人绕着一个足够大的园桌按顺时针坐成一圈, 每个人都有一个编号,编号从0开始,
* 从0号的人开始按顺时针报数,报的数从1开始, 凡是报的数字是7的倍数,或数字中有7, 这个人就从桌子上离开,
* 按顺时针方向后面的人继续进行报数.依此进行下去,最终桌上会剩下的最后一个人,问最后剩下的这个人的编号是几?
* 请编写一个C程序解决.如果用C++语言, 你又如何解决?
*
**/
#include "timer.h"
#include <stdio.h>
#include <string>
#include <cstddef>
#include <assert.h>
#include <iostream>
#include <exception>
#include <stdexcept>



class Element
{
public:
    unsigned long _data;
    Element* _pre;
    Element* _next;
    Element() : _pre ( NULL ), _next ( NULL ), _data ( 0 ) {}
};

Element*  CreatCircularList ( unsigned long N );
bool DeleteElementList ( Element *p );
/** N 个数,数到的数是base的整数倍,或是此数里含有base,就移除*/
// 为了降低难度,此处假设base 是7, pHead 是包含 N个元素的循环链表
void Detect7 ( Element* pHead, unsigned long base );
//判断num中是否存在 7, true, exist
bool CheckSeven ( unsigned long  num );


Element* gRelease = NULL;


int main ( int argc, char **argv )
{
    unsigned long  N;
    printf ( "How long do you want? please enter a positive number: " );
    scanf ( "%d", &N );

    gRelease = new Element;
    assert ( gRelease );
    Element* pHead = CreatCircularList ( N );
    assert ( pHead );

    // init the list
    for ( int i = 0; i != N ; ++i ) {
        pHead->_data = i;
        pHead = pHead->_next;
    }

    TimeStart();
    Detect7 ( pHead, 7 );
    TimeStop();
    printf ( "process time is : %f us \n", GetElapsedTime() );

    DeleteElementList ( gRelease );

#ifdef _WIN32
    system ( "pause" );
#endif
}

Element*  CreatCircularList ( unsigned long  N )
{
    assert ( N > 0 );

    TimeStart();
    Element *head = new Element;
    assert ( head != NULL );

    Element *cur = NULL;
    cur = head;
    try {
        for ( unsigned long  i = 0; i != N - 1; ++i ) {
            //
            Element * temp = new Element;
            assert ( temp != NULL );
            temp->_pre = cur;                   // temp point to previous
            cur->_next = temp;                  // previous point to temp
            cur = cur->_next;

        }
        cur->_next = head; // circular linked list
        head->_pre = cur;
    } catch ( const std::bad_alloc& err ) {
        printf ( "%s \n", err.what() );
        return NULL;
    }

    TimeStop();
    printf ( "Allocate memory time is : %f us \n", GetElapsedTime() );
    return head;

}

// release Element List
bool DeleteElementList ( Element *p )
{

    assert ( p != NULL );

    Element * rel = p;
    // int num = 0;
    while ( rel->_next ) {
        Element * temp = rel;
        rel = rel->_next;
        delete temp;
        //++num;
    }
    delete rel;

    // printf ( "内存释放 %d  次\n", num );

    return true;
}

void Detect7 ( Element* pHead, unsigned long base )
{
    assert ( pHead > 0 );
    assert ( base > 0 );

    Element* pRelease = gRelease;
    Element* pCurrent = pHead;

    for ( unsigned long  i = 1;; ++i ) {
        if ( i == -1 ) {
            printf ( "over flow \n" );
            return;
        }

        if ( pCurrent->_data == pCurrent->_next->_data ) {//判断是否是最后一个元素
            printf ( "The last member is %d \n", pCurrent->_data );
            //for release
            pRelease->_next = pCurrent;
            pRelease = pRelease->_next;
            pRelease->_next = NULL;
            return;
        }

        if ( i % 7 == 0 ) { //判断是否是7 的倍数
            pCurrent->_pre->_next = pCurrent->_next;
            pCurrent->_next->_pre = pCurrent->_pre;
            //for release
            pRelease->_next = pCurrent;
            pRelease = pRelease->_next;

            pCurrent = pCurrent->_next;
            continue;
        }
        if ( CheckSeven ( i ) ) { //判断是否包含7
            pCurrent->_pre->_next = pCurrent->_next;
            pCurrent->_next->_pre = pCurrent->_pre;
            //for release
            pRelease->_next = pCurrent;
            pRelease = pRelease->_next;

            pCurrent = pCurrent->_next;
            continue;
        }

        pCurrent = pCurrent->_next;
    }

    return;

}

//判断num中是否存在 7, true, exist
bool CheckSeven ( unsigned long  num )
{

    if ( num <= 0 ) return false;

    unsigned long  ret = num;
    unsigned long  remainder = 0;

    remainder = ret % 10; //求个位上的数字是几
    if ( remainder == 7 )
        return true;
    else
        CheckSeven ( num / 10 );

}

#include "timer.h"



i64 time_start ;
i64 time_stop ;
i64 time_freq ;

void TimeStart()
{
#if _WIN32
    QueryPerformanceFrequency ( ( LARGE_INTEGER * ) &time_freq );
    QueryPerformanceCounter ( ( LARGE_INTEGER * ) &time_start );
#elif __linux__
    time_freq = 1000;
    struct timeval s;
    gettimeofday ( &s, 0 );
    time_start = ( i64 ) s.tv_sec * 1000 + ( i64 ) s.tv_usec / 1000;
#endif
}

void TimeStop()
{
#if _WIN32
    QueryPerformanceCounter ( ( LARGE_INTEGER * ) &time_stop );
#elif __linux__
    struct timeval s;
    gettimeofday ( &s, 0 );
    time_stop = ( i64 ) s.tv_sec * 1000 + ( i64 ) s.tv_usec / 1000;
#endif
    time_stop -= time_start;
}

double GetElapsedTime()
{
    // unit: us
    return ( double ) time_stop * 1000000 / ( double ) time_freq;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值