首页 > 试题广场 >

序号4

[编程题]序号4
  • 热度指数:3055 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

输入描述:
一行,一个正整数n(1<=n<=1000000)。


输出描述:
输出答案。
示例1

输入

5

输出

4

说明

出局的编号依次为3,1,5,2,最后留下的是4

备注:
编号从1开始。
#include<cstdio>
int main()
{
    int cir[1000001];      //足够大的数组,存放每一个人的下一位是几号
    int n;                 //人数
    scanf("%d", &n);
    for(int i = 1;i < n;i++)
        cir[i] = i + 1;    //初始时,i号人下一位为i+1号人 (除n外)
    cir[n] = 1;            //第n号人下一位为1号,形成一圈
    int j = 1, k = 1;      //轮到第j个人报数字k
    /*模拟报数*/
    while(j != cir[j])     //如果j的下一个是自己,则跳出循环
    {
        k++;
        if(k != 3)         //如果报数不为三
            j = cir[j];    //轮到下一人
        else               //否则
        {
            cir[j] = cir[cir[j]];    //修改下一人为下一人的下一人(类似于删除链表中节点)
            j = cir[j];    //第j人(下一人)报数字1
            k = 1;
        }
    }
    printf("%d", j);
    return 0;
}
编辑于 2020-09-30 09:05:52 回复(1)
C++数学方法
#include<iostream>
using namespace std;
int main() {
    int n;
    while (cin >> n) {
        int res = 0;
        for (int i = 2; i <= n; i++) {
            res = (3 + res) % i;
        }
        cout << res + 1 << endl;
    }
    return 0;
}
发表于 2021-08-23 15:50:27 回复(0)
典型的环形链表 处理约瑟夫环问题
  public static int YueSeFuCircle(int n)
        {
            if (n == 1) return 1;
            Node head = new Node(1);
            Node cur = head;
            for (int i = 2; i <= n; i++)
            {
                cur.next = new Node(i);
                cur = cur.next;
            }
            cur.next = head;
            Node pre = null;
            cur = head;
            int count = 1;
            while(cur != pre)
            {
                if(count%3 != 0)
                {
                    pre = cur;
                    cur = cur.next;
                    count++;
                }
                else
                {
                    cur = cur.next;
                    pre.next = cur;
                    count = 1;
                }
            }
            return cur.val;
        }

发表于 2020-02-26 23:24:58 回复(1)
Java,突发奇想,使用队列,很简单
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 1; i <= n; i++) {
            queue.add(i);
        }
        while (queue.size() != 1) {
            for (int i = 0; i < 2; i++) {
                queue.add(queue.poll());
            }
            queue.poll();
        }
        System.out.println(queue.peek());
    }
}

发表于 2023-08-13 16:46:20 回复(1)
/**
* 楼上一位老兄的代码,我做了注释补充
*/
public static int YueSeFuCircle(int n) {

        // 边界值
        if (n == 1) return 1;

        Node head = new Node(1);

        Node cur = head;

        // 构造单链表
        for (int i = 2; i <= n; i++) {
            cur.next = new Node(i);
            cur = cur.next;
        }
        // 将尾结点的next指向头节点,形成环链
        cur.next = head;
        // 设置上一个结点
        Node pre = null;
        cur = head;

        int count = 1;

        while(cur != pre) {
              // 报数未达3,将当前结点后移,上一个结点跟着往后移
            if(count%3 != 0) {
                pre = cur;
                cur = cur.next;
                count++;
            }
            // 报数达到3,将当前结点的上一个结点的next指向当前结点的next
            // 相当于是删除链表中这个结点,
            // 再将count置为1,当前结点变成当前结点的下一结点
            else {
                cur = cur.next;
                pre.next = cur;
                count = 1;
            }

        }
        return cur.val;
    }

// 链表结点
static class Node{

    public Node(int val){
       this.val = val;
     }
    private int val;
    private Node next;
   }

发表于 2022-04-29 19:06:16 回复(0)
JavaScript(Node) 😎题目:4399👾-约瑟夫环
const readline = require('readline')
const rl = readline.createInterface({
    input: process.stdin,
    ouput: process.stdout
})
let inArr = []
rl.on('line', line=>{
    if(!line) return
    inArr.push(line.trim())
    if(inArr.length === 1){
        let n = +inArr[0]
        let res = lastRemaining(n,3)
        console.log(res+1)

    }
})

var lastRemaining = function(n, m) {
    let res = 0
    for(let i =2;i<=n;i++){
        res = (res+m)%i
    }
    return res
};


发表于 2020-03-09 15:18:08 回复(0)
#include <stdio.h>
int main()
{
    int a[1000000];      //足够大的数组,存放每一个人的下一位是几号
    int n;                 //人数
    scanf("%d", &n);
    for(int i = 0;i < n;i++)
        a[i] = i + 1;    //初始时,i号人下一位为i+1号人 (除n外)
               //第n号人下一位为1号,形成一圈
    int j = 0, k = 0,m=0;      //轮到第j个人报数字k
    /*模拟报数*/
    while(j==0)
    {
        for(int i=0;i<n;i++)
        {
            if(a[i]!=0)
            {
                k++;
                j++;
            }
            if(k==3)
            {
                a[i]=0;
                k=0;
            }
           
        }
        if(j==1)
        {
            j=1;
        }
        else
        {
            j=0;
        }
    }
    while(a[m]==0)
    {
        m++;
    }
  
    printf("%d", a[m]);
    return 0;
}
发表于 2020-10-13 21:39:55 回复(0)
用队列做法,队列:1,2,3....n,遍历队列,将所有不为3倍数的数字依次出列重新入队,叫号为3的倍数的数字出列后不入队,第一次后的结果为队列:1,2,4,5....n(n%3 != 0)
#include <iostream>
#include <queue>
using namespace std;
 
intmain() {
    queue<int> que;  
    intn;
    cin >> n;
 
    for(inti = 1; i <= n; i++){
        que.push(i);
    }
 
    intkey = 0;
    inttoken = 1;
    while(!que.empty()){
        key = que.front();
        que.pop();
        if(token%3== 0){
            token++;
            continue;
        }else{
            que.push(key);
            token++;
        }    
    }
    cout << key << endl;
 
}
发表于 2024-04-14 11:48:15 回复(0)
#include <iostream>
#include <queue>
using namespace std;

int main() {
    int a,count = 1;
    cin>>a;
    queue<int> q;

    for(int i = 0; i<a;i++){
        q.push(i + 1);
    }

    while (q.size() > 1) {
        if(count++ == 3){
            count = 1;
        }else{
            q.push(q.front());
        }
        q.pop();
    }
    cout<<q.front();
}
// 64 位输出请用 printf("%lld")

发表于 2024-03-09 04:43:48 回复(0)
Java
超时了

int n = scanner.nextInt();
List<Integer> group = new LinkedList<>();
for (int i =1;i<=n;i++){
group.add(i);
}
//索引记录
int record = 0;
while (group.size()>1){
record = (record + 3 - 1)% group.size(); //计算出局人的下标
System.out.println("出局:"+group.get(record)+"下标为:"+record);
group.remove(record);
}
System.out.println(group.get(0));

发表于 2023-05-08 23:07:34 回复(1)
//约瑟夫环(C语言)
int GetPeople(int n){
    if(n==1)return 1;
    int *people=(int*)malloc((n+1)*sizeof(int));
    memset(people,0,(n+1)*sizeof(int));
    int j=0;//计数器
    int outCount=0;//出局人数
    for(int i=1;outCount<n-1;i++){
        if(i>n){//保证循环
            i=1;
        }
        if(people[i]==0){//people还未出局
            j++;
            if(j%3==0){
                j=0;//计数再次从1开始
                people[i]=1;
                outCount++;
            }
        }
    }
    for(int i=1;i<=n;i++){
        if(people[i]==0)return i;
    }
    return 0;
}
int main(){
    int n=0,x;
    scanf("%d",&n);
    x=GetPeople(n);
    printf("%d",x);
}

发表于 2022-04-07 22:04:15 回复(0)
舍友用ArrayList超时了,所以我改用了LinkedList
import java.util.LinkedList;
import java.util.Scanner;

/**
 * @Author: Yr-zwx
 * @Date: 2021/10/16
 * @Content:
 */
public class Main {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        int nextInt = scanner.nextInt();

        LinkedList<Integer> integers = new LinkedList<>();
        int count=1;

        for (int i = 0; i < nextInt; i++) {
            integers.add(i+1);
        }

        while (true){

            if (integers.size()==1){
                break;
            }

            if (count%3==0){
                integers.pollFirst();
                count=1;
            }
            else {
                integers.addLast(integers.pollFirst());
                count++;
            }
        }
        System.out.println(integers.peek());

    }
}
--610 (懂哥至水哥)

发表于 2021-10-16 22:02:49 回复(0)
#include <stdio.h>
int main()
{
    int n,i,temp,count = 0;
    int num = 0;
    int index = 0;
    scanf("%d",&n);
    int a[n];
    for(i = 0; i < n; i++)
    {
        a[i] = i + 1;
    }
    while(count != n-1)
    {
        if(a[index] != 0)
        {
            num++;
        }
        if(num == 3)
        {
            a[index] = 0;
            num = 0;
            count++;
        }
        index++;
        if(index > n - 1)
        {
            index = index - n;
        }
        
    }
    for(i = 0;i < n;i++)
    {
        if(a[i] != 0)
        {
            printf("%d",a[i]);
        }
    }
}
发表于 2021-10-16 14:11:54 回复(0)
约瑟夫问题
n = int(input())
res = 0;
for i in range(2, n + 1):
    res = (3 + res) % i
print(res + 1)

编辑于 2021-10-06 15:20:57 回复(0)
//用Java数组实现约瑟夫环问题
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        //数组解决约瑟夫环问题
        int[] p = new int[n];
        int[] flag = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = i + 1;       //初始化数组
            flag[i] = 0;   //初始默认都在圈里
        }
        int c = 0;  //当前喊的人的牌号
        int k = 0;  //当前喊的数
        int targetNum = 3;  //出圈口令,喊到3就出圈
        int outNum = 0; //当前已出圈人数
        while (outNum != n - 1){    //当当前已出圈人数 不等于 输入的人数时
            c++; //1号位准备喊数
            if (c > n){ //如果当前喊的人的位子大于所有人数
                c = 1; //从头再来
            }
            if(flag[c-1] == 0){ //如果这个人在圈里
                k++; //让他喊数
                if (k == targetNum){  //如果喊得数是目标值3,就出圈
                    flag[c-1] = 1;  //标志已出圈,不再参与下一轮
                    outNum++;  //出圈人数增加
                    k = 0;  //只要一喊到3,就初始化下一轮的喊数
                    //System.out.print(c + " ");    //打印出圈顺序
                }
            }
        }
        //找到剩下的唯一flag=0的人并输出
        for (int i = 0; i < flag.length; i++) {
            if (flag[i] == 0){
                System.out.println(p[i]);
            }
        }
    }
}

发表于 2021-09-09 23:00:04 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args) { 
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        int num = 0;
        int person = n;
        for (int i = 0;i < n;i++){
            a[i] = i + 1;
        }
        for (int i = 0;;i++){
            if (i == n){
                i = 0;
            }
            if (a[i] != 0){
                num++;
            }else{
                continue;
            }
            if(num == 3){
                a[i] = 0;
                person--;
                num = 0;
            }
            if(person == 1){
                break;
            }
        }
        for (int i = 0;i < n;i++){
            if (a[i] != 0){
                System.out.println(a[i]);
            }
        }
    }
}

发表于 2021-08-20 15:37:05 回复(0)
#include <stdio.h>

const int m = 3;
int main()
{
	int n, f = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) f = (f + m) % i;
	printf("%d", f+1);
	system("pause");
	return 0;
}


发表于 2021-03-03 17:33:09 回复(0)
超时了思路应该没问题

import java.util.ArrayList;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        System.out.println(demo01(n));
//        System.out.println(2/5);
//        System.out.println(demo01(6));
    }
    public static int demo01(int n){
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 1; i <=n ; i++) {
            list.add(i);
        }
        int index=-1;
        while (list.size()>1){
            index+=3;
            index=index%n;
            list.remove(index);
            index-=1;
            n--;
        }
        return list.get(0);
    }
}
发表于 2020-10-23 17:46:48 回复(0)
while True:
    try:
        n = int(input())
        s = list(range(1, n+1))
        count = 0
        while len(s)>1:
            s1 = s[:]
            for i in range(0, len(s1)):
                count += 1
                if count%3 == 0:
                    s.remove(s1[i])
        print(s[0])
    except:
        
超时了,我好菜啊。。。唉 找不到工作
发表于 2020-08-20 17:55:47 回复(0)
约瑟夫环
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int pos=0;
    for(int i=2;i<=n;i++)
    {
        pos=(pos+3)%i;
    }
    cout<<pos+1;
    return 0;
}


发表于 2020-07-17 11:53:12 回复(0)