51Nod1074 约瑟夫环 V2

题意

约瑟夫环,N-1e18,K-1000

思路

由于K远小于N,后面i大了之后某些时候不用取模,可以加速。

代码

#include<iostream>
#include<cstdio>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll n,k;
ll cur,t;
int main(){
    cin>>n>>k;
    cur=0;
    for(ll i=2;i<=n;i+=t+1){
        t=(i-cur)/k-1;
        if(t<0) t=0;
        if(i+t+1>n) t=n-i;
        cur=(cur+(t+1)*k)%(i+t);
    }
    cur++;
    cout<<cur<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/sz-wcc/p/11231635.html

时间: 2024-11-12 10:59:29

51Nod1074 约瑟夫环 V2的相关文章

1074 约瑟夫环 V2

1074 约瑟夫环 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 收藏 关注 N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数.问最后剩下的人的编号. 例如:N = 3,K = 2.2号先出列,然后是1号,最后剩下的是3号. Input 2个数N和K,表示N个人,数到K出列.(2 <= N <= 10^18, 2 <= K <= 1000) Output 最后剩下的人的编号 Input

约瑟夫环以及其变种集合

最近在CF上补题,补到了一道关于约瑟夫环的题目(听都没听过,原谅我太菜) 就去好好学了一下,不过一般的题目应该是不会让你模拟过的,所以这次就做了一个约瑟夫环公式法变形的集合. 关于约瑟夫环的基础讲解,我个人认为最好的就是这篇了. 首先是最原始的约瑟夫环的题目: https://vjudge.net/problem/51Nod-1073(小数据规模) #include <bits/stdc++.h> using namespace std; int main() { ios::sync_with

一个不简洁的约瑟夫环解法

约瑟夫环类似模型:已知有n个人,每次间隔k个人剔除一个,求最后一个剩余的. 此解法为变种,k最初为k-2,之后每次都加1. 例:n=5,k=3.从1开始,第一次间隔k-2=1,将3剔除,第二次间隔k-1=2,将1剔除.依此类推,直至剩余最后一个元素. 核心思路:将原列表复制多份横向展开,每次根据间隔获取被剔除的元素,同时将此元素存入一个剔除列表中.若被剔除元素不存在于剔除列表,则将其加入,若已存在,则顺势后移至从未加入剔除列表的元素,并将其加入.如此重复n-1次.面试遇到的题,当时只写了思路,没

ytu 1067: 顺序排号(约瑟夫环)

1067: 顺序排号Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 31  Solved: 16[Submit][Status][Web Board] Description 有n人围成一圈,顺序排号.从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位. Input 初始人数n Output 最后一人的初始编号 Sample Input 3 Sample Output 2 HINT Source freepro

约瑟夫环 C语言 单循环链表

/*---------约瑟夫环---------*/ /*---------问题描述---------*/ /*编号为1,2,-,n的n个人围坐一圈,每人持一个密码(正整数). 一开始任选一个正整数作为报数上限值m, 从第一个人开始自1开始顺序报数,报到m时停止. 报m的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数, 如此下去,直至所有人全部出列为止.试设计一个程序求出列顺序.*/ /*---------问题分析---------*/ /*n个人围坐一圈,且不断有人出列,即频繁

循环单向链表(约瑟夫环)

#include <stdio.h> #include <stdlib.h> typedef struct List { int data; struct List *next; }List; //创建循环单向链表n为长度 List *list_create(int n) { List *head, *p; int i; head = (List *)malloc(sizeof(List)); p = head; p->data = 1; //创建第一个结点 for (i =

约瑟夫环问题

(约瑟夫环问题)有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那个人. package aiqiyi; import java.util.ArrayList; public class Main { public static int leftPerson(int n) { // 用list来保存n个人,序号为1~n ArrayList<Integer> list = new ArrayList<Integer>()

cdoj525-猴子选大王 (约瑟夫环)

http://acm.uestc.edu.cn/#/problem/show/525 猴子选大王 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 有m个猴子围成一圈,按顺时针编号,分别为1到m.现打算从中选出一个大王.经过协商,决定选大王的规则如下:从第一个开始顺时针报数,报到n的猴子出圈,紧接着从下一个又从1顺时针循环报数,...,如此下去,最后剩

约瑟夫环——POJ3379

题目描述: 给出一个长度是n的字符串环,每次搁k个加入字符串中对应位置的字母序的下一个字母,执行m次,问最后一次插入的是什么字母. 大致思路: 正着想的话只能用模拟的方法解决,但是m有10^9这么大,而把问题倒过来想一下的话,那就变成了给出一个n+m的字符串每次搁k个字符删掉一个,最后剩下一个长度为n的字符串,问起始位置是什么字母.这样的话就变成了约瑟夫问题,约瑟夫环问题可以在不用考虑内容的情况下计算出最后剩下元素的位置.又因为字符串是一个环,所以可以假定开始的位置就是1,最后操作结束的位置就是