zoukankan      html  css  js  c++  java
  • 线性表——约瑟夫问题(递推未完)

    题目链接
    总时间限制: 1000ms 内存限制: 65536kB
    描述
    有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

    输入
    输入包含两个整数,第一个是n,第二个是m (0 < m,n <=300)。
    输出
    输出包含一行,即最后猴王的编号。
    样例输入

    12 4
    

    样例输出

    1
    

    这道题是有好几种解法的。
    首先是数组链表遍历后删除的算法。

    1.链表模拟
    分析:建立一个循环链表,递推,一个个删除直到只剩下一个,输出即可。

    2.静态链表模拟
    分析:用数组模拟链表,就是数组里存的是下一个位置的下标。

    以上两种的时间复杂度均为O(n*m);

    3.数组模拟
    分析:先初始化整个数组为1,接下来在循环中只对数值为1的进行计数,满n置0,最后遍历最后一个数值为1的数,输出其下标。
    这种的时间复杂度最大,为O(n^2);

    4.递推算法
    待考试周过去后写

    1.链表遍历算法

    #include <stdio.h>
    #include <stdlib.h>
    #define N 10000
    
    typedef struct node{
        int data;
        struct node* next;
    }node,*nodePtr;
    
    void Create(nodePtr head, int n ){
        nodePtr temp, last = head;
        for(int i = 1;i <= n;i++){
            temp = (nodePtr)calloc(1,sizeof(node));
            if(temp == NULL) return ;
            temp -> data = i;
            last -> next = temp;
            //printf("%p	%p	%p	%p
    ",NULL,head,last,last->next);
            last = temp;
            //printf("%d
    ",last->data);
        }
        last -> next = head -> next;
        //printf("%p	%p	%p	%p
    ",NULL,head,last,last->next);
    }
    
    void Del(nodePtr prev, nodePtr &curr){
        nodePtr temp = curr;
        prev->next = curr -> next;
        curr = prev;
        free(temp);
    }
    
    nodePtr Josephus(nodePtr head,int m){
        nodePtr temp = head,prev = NULL;
        while(head->next != head){
            for(int i = 0;i < m;i++){
                prev = head;
                head = head -> next;
                //printf("%p	%p
    ",prev,head);
            }
            //printf("%d
    ",head->data);
            Del(prev,head);
        }
        free(temp);
        return head;
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            nodePtr head = NULL;
            head = (nodePtr)malloc(sizeof(node));
            head -> next = NULL;
            Create(head, n);
            printf("%d
    ",Josephus(head,m)->data);
        }
        return 0;
    }
    

    2.静态链表算法

    #include <stdio.h>
    #include <stdlib.h>
    
    #define N 10000
    
    int main(){
        int a[N];
        int n,m;
        scanf("%d%d",&n,&m);
    
        for(int i = 0;i < n;i++){
            a[i] = i+1;
        }
        a[n] = 1;
    
        int k = 0;
        int prev;
        while(a[k] != k){
            for(int i = 1;i <= m;i++){
                prev = k;
                k = a[k];
            }
            a[prev] = a[k];
        }
        printf("%d
    ",k);
        return 0;
    }
    

    3.数组模拟算法

    #include <stdio.h>
    #include <stdlib.h>
    #define N 350
    
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        int a[N];
        int cnt = 0;
        int times = 0;
        for(int i = 1;i <= n;i++)
            a[i] = 1;
    
        int i = 1;
        while(times!=n-1){
            while(1){
                if(a[i++] == 1){
                    cnt++;
                    if(cnt > 0 && cnt%m == 0)
                        break;
                }
                if(i > n)
                    i = i%n;
            }
            a[i-1] = 0;
            if(i > n)
                i = i%n;
            times++;
        }
        for(i = 1;i<=n;i++)
            if(a[i] == 1)
                break;
        printf("%d
    ",i);
        return 0;
    }
    
  • 相关阅读:
    火眼金睛算法,教你海量短文本场景下去重
    CynosDB技术详解——架构设计
    CynosDB技术详解——存储集群管理
    解决 "Script Error" 的另类思路
    Go 语言实践(一)
    Vue.js的复用组件开发流程
    MYSQL中的COLLATE是什么?
    Blending
    AlphaTesting
    Culling & Depth Testing
  • 原文地址:https://www.cnblogs.com/sean10/p/4985729.html
Copyright © 2011-2022 走看看