青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

/*
  Name: 約瑟夫環問題算法集錦
  Copyright: 始發于goal00001111的專欄;允許自由轉載,但必須注明作者和出處
  Author: goal00001111搜集整理
  Date: 03-12-08 18:14
  Description:
有編號從1到N的N個人坐成一圈報數,報到M的人出局,下一位再從1開始, 如此持續,
直止剩下一位為止,報告此人的編號X。
輸入N,M,求出X。
共搜集整理了7類10種算法,對于初學者和算法愛好者來說——看了絕對值!
*/
#include<iostream>
#include <time.h>

using namespace std;

int Fun_1(int n, int m);
int Fun_2(int n, int m);
int Fun_3(int n, int m);
int Fun_4(int n, int m);
int Fun_5(int n, int m);
int Fun_6(int n, int m);
int Fun_7(int n, int m);
int Fun_8(int n, int m);
int Fun_9(int n, int m);
int Fun_10(int n, int m);

int main(int argc, char* argv[])
{
    int n, m;
    //cout << "Input max, step: ";
//    cin >> n >> m;
    time_t startTime;
    time_t endTime;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_1(i, 8);
    time(&endTime);
    cout << "No.1 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_2(i, 8);
    time(&endTime);
    cout << "No.2 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_3(i, 8);
    time(&endTime);
    cout << "No.3 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_4(i, 8);
    time(&endTime);
    cout << "No.4 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_5(i, 8);
    time(&endTime);
    cout << "No.5 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_6(i, 8);
    time(&endTime);
    cout << "No.6 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_7(i, 8);
    time(&endTime);
    cout << "No.7 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_8(i, 8);
    time(&endTime);
    cout << "No.8 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_9(i, 8);
    time(&endTime);
    cout << "No.9 time = " << difftime(endTime, startTime) << endl;
   
    time(&startTime);
    for (int i=10; i<11; i++)
       cout << Fun_10(i, 8);
    time(&endTime);
    cout << "No.10 time = " << difftime(endTime, startTime) << endl;
   
    system("pause");
    return 0;
}

//采用了設置個人編號和計數器方法,屏蔽已經出圈人的位置
int Fun_1(int n, int m)
{
    int *a = new int[n]; //設置一個數組用來存儲n個人的編號
   
    for (int i=0; i<n; i++) //注意C語言中的數組下標從0開始
    {
        a[i] = i + 1;
    }
    int s = 1; //累計出圈的人數,設初值為1,那最后一個就不用出圈了
    int count = 0; //計數器,數到m就歸零
   
    while(s < n)
    {
        for (int i=0; i<n; i++)//只要還有超過1個人在圈里,就不斷的遍歷數組
        {
            if (a[i] == 0) //編號為0,表示此人已經出圈
                continue;
            count++;    //報一次數
            if (count == m) //報數為m的那個人出圈
            {
                a[i] = 0; //設此位置編號為0,表示此人已經出圈
                ++s; //出圈人增加一個
                count = 0; //計數器歸零
            }
        }
    }
    int pos;
    for (int i=0; i<n; i++) //遍歷數組,看看還有誰沒有出圈,找的就是他
    {
        if (a[i] != 0)
        {
            pos = a[i];
            break;
        }
    }
    delete []a;
    return pos;
}

//采用了計數器方法,也使用了數組,但數組中存儲的不是個人的編號,而是是否出圈的信息
int Fun_2(int n, int m)
{
    int *a = new int[n]; //設置一個數組用來存儲n個人是否出圈,1表示在圈內,0表示在圈外
   
    for (int i=0; i<n; i++) //首先設置所有人都在圈內
    {
        a[i] = 1;
    }
    int s = 1; //累計出圈的人數,設初值為1,那最后一個就不用出圈了
    int count = 0; //計數器,數到m就歸零
   
    while(s < n)
    {
        for (int i=0; i<n; i++)//只要還有超過1個人在圈里,就不斷的遍歷數組
        {
            count += a[i]; //若a[i]=0,就直接跳過了
            if (count == m) //報數為m的那個人出圈
            {
                a[i] = 0; //設此位置編號為0,表示此人已經出圈
                ++s; //出圈人增加一個
                count = 0; //計數器歸零
            }
        }
    }
    int pos;
    for (int i=0; i<n; i++) //遍歷數組,看看還有誰沒有出圈,找的就是他
    {
        if (a[i] == 1)
        {
            pos = i + 1;
            break;
        }
    }
    delete []a;
    return pos;
}

//采用了數組隊列的方法,每出圈一個人,就從隊列中刪除
int Fun_3(int n, int m)
{
    int *a = new int[n]; //設置一個數組用來存儲n個人的編號
   
    for (int i=0; i<n; i++) //注意C語言中的數組下標從0開始
    {
        a[i] = i + 1;
    }
    int front=0, rear=n-1;  //對頭front指向第一個元素,隊尾rear指向最后一個元素
    int count = 0; //計數器,數到m就歸零
   
    while ((front) != (rear))//當隊列元素還有一個,注意這里不需要隊列為空,而是留一個元素
    {
        count++;    //報一次數
        if (count == m) //報數為m的那個人出圈
        {
            front = ++front % n; //將該元素從隊列中刪除
            count = 0; //計數器歸零
        } 
        else //否則把對頭的元素放到隊尾去
        {
            rear = ++rear % n;//隊尾前移,以存儲從對頭轉來的元素
            a[rear] = a[front];
            front = ++front % n; //對頭前移,指向新的元素
        }           
    }
    delete []a;
    return a[front]; 
}

//很巧妙的方法,不用屏蔽位置, 需要計數器,采用數組,但數組中存儲的不是本人的編號,而是是下一個人的編號 
int Fun_4(int n, int m)
{
    int *a = new int[n]; //設置一個數組用來存儲n個人是否出圈,1表示在圈內,0表示在圈外
   
    for (int i=n-2; i>=0; i--) //存儲下一個人的編號
    {
        a[i] = i + 1;
    }
    a[n-1] = 0; //最后一個人的下一位是第一個人
    int s = 0; //累計出圈的人數,設初值為1,那最后一個就不用出圈了
    int count = 0; //計數器
    int pos; //當前位置
    int nextPos = 0;//下一位置
   
    while(s < n)
    {
        pos = nextPos;//獲取當前位置
        nextPos = a[pos];//獲取當前位置的下一位置
        count++;
        if (count == m)//改變當前位置的下一位置
        {
            count = 0; //計數器歸零
            s++; //累計出圈人
            a[pos] = a[nextPos];
        }  
    }
   
    delete []a;
   
    if (nextPos != 0)
        return nextPos;
    else
        return n;
}

//很巧妙的方法,Fun_4()的一個改進
int Fun_5(int n, int m)
{
   int *a = new int[n]; //設置一個數組用來存儲n個人是否出圈,1表示在圈內,0表示在圈外
   
    for (int i=n-2; i>=0; i--) //存儲下一個人的編號
    {
        a[i] = i + 1;
    }
    a[n-1] = 0; //最后一個人的下一位是第一個人
    int pos = n - 1; //當前位置
   
    do
    {
        for (int i=0; i<m-1; i++)
            pos = a[pos]; 
        a[pos] = a[a[pos]];
    } while (pos != a[pos]);
   
    delete []a;
   
    return pos + 1;
}

//很巧妙的方法,直接確定出列的人,并不斷改變數組的長度
int Fun_6(int n, int m)
{
    int *a = new int[n]; //設置一個數組用來存儲n個人的編號
   
    for (int i=0; i<n; i++) //注意C語言中的數組下標從0開始
    {
        a[i] = i + 1;
    }
   
    int pos = (m - 1) % n;//這是第一個要出列的人的下標
   
    while (n > 1) // 當隊列中還有不止一個人的時候,要就進行出列的動作
    {
        for (int i=pos; i<n-1; i++) //這個家伙走了以后,后面的人應該依次頂上來
        {
            a[i] = a[i+1];
        }
        n--;    // 并且整個隊列的人少了一個,也就是長度要減掉一
        pos = (pos + m - 1) % n; //這是下一個要出列的人
    }
    pos = a[0];
    delete []a;
    return pos;
}

//采用循環鏈表結構,來進行刪除操作
int Fun_7(int n, int m)
{
    struct node
    {
        int data;
        struct node *next;
    };
    struct node * head, *s, *temp;
    head = new struct node;//存儲第一個人的序號信息
    head->data = 1;
    temp = head->next = head;
    for (int i=2; i<=n; i++)//存儲所有人的序號信息
    {
        s = new struct node;
        s->data = i;
        s->next = head;
        temp->next = s;
        temp = s;
    }
    s = head;
    while (s->next != s)
    {
        for (int i=1; i<m; i++)//先數m-1個數
        {
            temp = s;
            s = s->next;
        }
        //把數到m的人從鏈表中刪除
        temp->next = s->next;
        delete s;
        s = temp->next;
    }
    int pos = s->data; //最后一個人
    delete s;
    return pos;
}

/*
數學方法:
令f表示i個人玩游戲報m退出最后勝利者的編號,最后的結果自然
是f[n],因為實際生活中編號總是從1開始,我們輸出f[n]+1
遞推公式
f[1]=0;
f=(f[i-1]+m)%i;   (i>1)
*/
// 遞歸算法
int F(int n, int m)
{
    if (n == 1)
      return 0;  
    return (F(n-1, m) + m) % n;
}
int Fun_8(int n, int m)
{    
    return F(n, m) + 1;
}

//非遞歸算法
int Fun_9(int n, int m)
{
    int r = 0;
    for (int i = 2; i <= n; i++)
        r = (r + m) % i;
    return r + 1;
}

int Fun_10(int n, int m)
{
    int p, i = 1;
    while( i < n )
    {
        p = i * m;
        while (p > n)
            p = p - n + (p - n - 1)/(m - 1);
        i++;
    }
    p = n * m;
    while (p > n)
        p = p - n + (p - n - 1)/(m - 1);
       
    return p;
}


Posted on 2008-12-03 18:22 夢想飛揚 閱讀(510) 評論(1)  編輯 收藏 引用

Feedback

# re: 約瑟夫環問題算法集錦[未登錄]  回復  更多評論   

2008-12-04 12:19 by 908971
受教了
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美专区在线| 欧美va天堂| 精品69视频一区二区三区| 国产精品午夜在线观看| 国产精品美女一区二区| 国产精品v欧美精品v日韩 | 免费观看在线综合| 蜜桃av一区二区在线观看| 女生裸体视频一区二区三区| 欧美aa国产视频| 欧美日韩国产不卡在线看| 欧美视频网站| 国产亚洲成av人在线观看导航| 国产日韩亚洲| 亚洲国内高清视频| 在线亚洲自拍| 久久女同精品一区二区| 欧美高清一区二区| 国产精品99久久久久久久久| 欧美一级视频免费在线观看| 另类春色校园亚洲| 国产精品久久久久久久久久免费看 | 国产一区欧美日韩| 91久久久久久久久久久久久| 亚洲天堂av电影| 久久男人资源视频| 99re8这里有精品热视频免费| 亚洲综合久久久久| 欧美成人高清| 海角社区69精品视频| 9久re热视频在线精品| 久久久久国产精品麻豆ai换脸| 亚洲黄色毛片| 亚洲女性喷水在线观看一区| 欧美成人一品| 国产欧美日韩在线视频| 日韩小视频在线观看| 久久久www成人免费毛片麻豆| 亚洲看片免费| 模特精品在线| 激情成人亚洲| 欧美在线日韩| 一区二区三区免费网站| 老牛嫩草一区二区三区日本| 亚洲人成网站影音先锋播放| 欧美精品97| 国产精品少妇自拍| 性欧美精品高清| 久久岛国电影| 中文精品在线| 欧美日韩精品国产| 精久久久久久| 亚洲图片欧美一区| 国产日本欧洲亚洲| 欧美国产日韩一二三区| 欧美精品一区二区三区一线天视频| 亚洲欧洲一区| 亚洲欧美一区二区三区在线| 亚洲网站在线观看| 欧美精品www| 奶水喷射视频一区| 中文欧美在线视频| 欧美激情免费在线| 亚洲国产一区二区精品专区| 欧美一区二区三区免费在线看| 欧美亚韩一区| 正在播放亚洲| 在线一区二区三区四区五区| 久久亚洲欧美| 黄色日韩网站视频| 伊人春色精品| 国产精品a级| 亚洲免费观看高清完整版在线观看熊| 亚洲第一页在线| 精品动漫3d一区二区三区免费版| 欧美成人有码| 亚洲国产日韩欧美一区二区三区| 国产亚洲aⅴaaaaaa毛片| 亚洲精品影院在线观看| 欧美日韩精品二区| 久久视频在线看| 尤物九九久久国产精品的分类| 亚洲国产精品一区二区久| 中文日韩欧美| 久热精品视频在线观看一区| 亚洲区一区二| 国产欧美日韩一区二区三区在线| 欧美91视频| 久久久91精品| 国产日韩精品一区二区三区在线| 亚洲国产精品第一区二区三区| 美女啪啪无遮挡免费久久网站| 亚洲图片激情小说| 久久全国免费视频| 久久久最新网址| 日韩一区二区高清| 亚洲一区在线免费观看| 国产亚洲激情在线| 亚洲电影免费在线| 国产精品va| 狼狼综合久久久久综合网| 欧美巨乳在线观看| 久久久免费观看视频| 老**午夜毛片一区二区三区| 亚洲一区二区三区视频| 午夜精品免费| 日韩视频免费大全中文字幕| 亚洲在线观看视频网站| 亚洲经典一区| 欧美一区二区精品在线| av成人动漫| 美女在线一区二区| 欧美一区二区成人| 欧美激情视频一区二区三区在线播放| 欧美在线观看日本一区| 欧美精品色综合| 久久综合九色欧美综合狠狠| 国产精品国产三级国产a| 亚洲高清av| **欧美日韩vr在线| 欧美一区二区三区喷汁尤物| 在线一区二区三区做爰视频网站| 久久精品三级| 欧美一区亚洲一区| 国产精品久久久久毛片软件| 亚洲国产精品一区二区久| 国产自产在线视频一区| 亚洲欧美成人网| 亚洲综合三区| 欧美日韩国产综合视频在线观看中文| 久久久中精品2020中文| 国产亚洲欧洲一区高清在线观看| 亚洲精品一级| 亚洲电影自拍| 久久精品国产欧美激情 | 亚洲专区一区| 亚洲线精品一区二区三区八戒| 欧美寡妇偷汉性猛交| 欧美高清视频在线| 亚洲国产精品成人va在线观看| 久久精品视频免费| 久久天堂精品| 一区二区在线观看视频在线观看| 欧美一级淫片aaaaaaa视频| 欧美一级免费视频| 国产日韩亚洲欧美精品| 午夜精品久久久久久久| 久久精品在线观看| 激情综合自拍| 女同性一区二区三区人了人一 | 亚洲欧美一区二区原创| 国产精品九九久久久久久久| 亚洲一区二区在线| 久久精品欧美日韩精品| 国产综合久久久久久鬼色| 久久久久久综合| 亚洲福利专区| 亚洲自啪免费| 国产麻豆综合| 久久人人看视频| 亚洲每日更新| 久久99在线观看| 亚洲黄色av一区| 欧美特黄一区| 久久精品国产69国产精品亚洲| 蜜桃久久精品一区二区| 99综合视频| 国产日韩精品久久久| 麻豆精品国产91久久久久久| 99re6热在线精品视频播放速度| 欧美一级视频免费在线观看| 在线播放不卡| 欧美视频在线免费看| 久久精品日韩| 亚洲网站啪啪| 欧美成人免费全部| 亚洲欧美日韩综合国产aⅴ| 韩国av一区二区三区| 欧美另类高清视频在线| 欧美一区二区国产| 日韩一区二区高清| 欧美大胆成人| 久久精品国产亚洲a| 日韩亚洲欧美一区二区三区| 国产日韩精品一区二区| 欧美精品一区二区视频| 久久爱www.| 亚洲网址在线| 亚洲精品欧美精品| 欧美v亚洲v综合ⅴ国产v| 亚洲欧美日本另类| 日韩亚洲在线| 亚洲国产女人aaa毛片在线| 国产欧美日韩伦理| 欧美日韩亚洲综合一区| 美女精品视频一区| 欧美在线视屏| 欧美一级片在线播放| 在线综合亚洲欧美在线视频| 亚洲电影免费在线观看|