今年7月份vivo迎来了新入职的大学生,现在需要为每个新同事分配一个工号。人力资源部同事小v设计了一个方法为每个人进行排序并分配最终的工号,具体规则是:
将N(N<10000)个人排成一排,从第1个人开始报数;如果报数是M的倍数就出列,报到队尾后则回到队头继续报,直到所有人都出列;
最后按照出列顺序为每个人依次分配工号。请你使用自己擅长的编程语言帮助小v实现此方法。
将N(N<10000)个人排成一排,从第1个人开始报数;如果报数是M的倍数就出列,报到队尾后则回到队头继续报,直到所有人都出列;
输入2个正整数,空格分隔,第一个代表人数N,第二个代表M:
输出一个int数组,每个数据表示原来在队列中的位置用空格隔开,表示出列顺序:
6 3
3 6 4 2 5 1
6个人排成一排,原始位置编号即为1-6。最终输出3 6 4 2 5 1表示的是原来编号为3的第一个出列,编号为1的最后一个出列。
void solution(int N, int M)
{
if (N <1||M<1)return;
vector<int> v(N);
for (int i = 0; i<N; i++)v[i] = i + 1;
int i = 0;
while (v.size()>0) {
i += M-1;
if (i>=v.size())i = i%v.size();
cout << v[i] << " ";
v.erase(i + v.begin());
}
cout << endl;
} void solution(int N, int M)
{
//构造环形链表
_node* head = new _node;
head->num = 1;
_node* pre = head;
for(int i = 2;i <= N;i++){
_node* temp = new _node;
temp->num = i;
pre->next = temp;
pre = pre->next;
}
pre->next = head;
//当M=1时,按顺序输出即可
if(M == 1){
for(int i = 0; i < N - 1;i++){
cout << head->num<< " ";
head = head->next;
}
cout << head->num;
return;
}
//当M>1时
while(head != NULL){
//找到要输出的节点的前一个节点
for(int i = 0;i < M - 2;i++){
head = head->next;
}
//输出当前节点下一个节点的元素
cout << head->next->num << " ";
//判断输出完后链表中是否只剩下了一个节点
if(head == head->next->next){
cout << head->num;
return;
}
//从链表中删除输出的节点,将当前节点的下一个节点指向删除的节点的下一个节点
head->next = head->next->next;
head = head->next;
}
} x = input() N = int(x.split()[0]) M = int(x.split()[1]) p = [i + 1 for i in range(N)] count = 1 index = 0 while len(p) > 0: if index >= len(p): index = index % len(p) if count % M == 0: print(p[index], end=" ") p[index] = 0 p.remove(p[index]) count += 1 continue count += 1 index += 1
import java.io.*;
import java.util.ArrayList;
/**
* Welcome to vivo !
*/
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputStr = br.readLine();
int input[] = parseInts(inputStr.split(" "));
String output = solution(input);
System.out.println(output);
}
private static int[] parseInts(String[] strArr) {
if (strArr == null || strArr.length == 0) {
return new int[0];
}
int[] intArr = new int[strArr.length];
for (int i = 0; i < intArr.length; i++) {
intArr[i] = Integer.parseInt(strArr[i]);
}
return intArr;
}
private static String solution(int[] input) {
// TODO Write your code here
StringBuilder sb = new StringBuilder();
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i < input[0]; i++)
list.add(i + 1);
int start = 1, pos = 0;
while(list.size() > 0){
if(start % input[1] == 0){
// pos位置的员工报到了m的倍数,出列
sb.append(list.remove(pos) + " ");
}else{
// 否则不出列,位置继续后移
pos ++;
}
// 到队尾后回到队首
if(pos >= list.size())
pos -= list.size();
// 报数
start ++;
}
return sb.toString().trim();
}
} function solution(n, m) {
let v = new Array(n+1);
let res = [];
for(let i=0;i<n;i++){
v[i] = i+1;
}
let j = 0;
while(v.length>0){
j += m-1;
if(j>=v.length) j = j%v.length;
res.push(v[j]);
v.splice(j,1);
}
let result = '';
for(let i=0;i<res.length;i++){
result += res[i]+' ';
}
return result;
}
while (line = readline()) {
var params = line.split(" ");
var n = params[0];
var m = params[1];
print(solution(n, m));
} def solution(N,M): li = list(map(int, range(1, N + 1))) sub = li k = 0 while sub: li = [] for i in range(len(sub)): k += 1 if k % M == 0: print(sub[i], end=' ') # 满足条件就输出 else: li.append(sub[i]) # 不满足就加进新的列表 sub = li # 最后将新的列表赋值,再进行循环 pass N,M = [int(i) for i in input().split()] solution(N,M)
def solution(N,M):
if N < 1&nbs***bsp;M < 1:
return
a = [i for i in range(1,N+1)]
count = 1
res = []
while a:
temp = []
for i in a:
if count%M != 0:
temp.append(i)
else:
res.append(i)
count += 1
a = temp
print(" ".join(map(str,res)))
return
N,M = [int(i) for i in input().split()]
solution(N,M) 1.选择数据结构方面,用List集合可以了,值得注意的是当有人出队时,后一个元素会前移代替当前元素的位置
2.做了两轮处理,将员工1~N放入List的时候就先报数一轮;第二轮将剩余的人出队
private static String solution(int[] input) {
//队列初始化+初次编号
List<Integer> employee=new ArrayList<Integer>();
employee.add(-2);//虚拟头结点填充,因为是从1开始报数
StringBuilder res=new StringBuilder();//输出
int N=input[0];//input[0]=N人数
int M=input[1];//倍数
int i=1;
while(i<=N){
if(i%M==0){
res.append(i).append(" ");//输出要求有空格
}else{
employee.add(i);
}
i++;
}
int count=N+1;//报了一轮数之后该有的值
//二次编号
while(true){
i=1;//从头开始重新报数
int len=employee.size();
if(len==1){//只剩下虚拟头结点时
break;
}
while(i<len){//i是数组的下标
if(count%M==0){
res.append(employee.get(i)).append(" ");//拿到该下标 i 对应的value
employee.remove(i);//从队列删除该下标i对应的值
len=employee.size();//删除之后后面的结点会补上原来的位置,但是len缩短了
count++;// 前一个人报数并出队后,后一个人代替了它的位置并报数+1(该处比较特殊)
continue;//下标指针i仍然停止当前位置(因为后面的数值往前移动了)
}
i++;
count++;
}
}
return res.toString();
}
struct Node {
int val;
Node* next;
Node(int v) : val(v), next(NULL) {};
};
void solution(int N, int M)
{
Node* head = new Node(1);
Node* curr = head;
for (int i = 2; i <= N; ++i) {
curr->next = new Node(i);
curr = curr->next;
}
curr->next = head;
Node* prev = curr;
curr = head;
for (int i = 1; i <= N; ++i) {
for (int j = 1; j < M; ++j) {
prev = curr;
curr = curr->next;
}
cout << (curr->val) << " ";
prev->next = curr->next;
curr = curr->next;
}
} 一个简单不易错的方法。 其他人的方法有些使用 erase 或者 remove 的操作删除元素,这个操作的复杂度是O(n),使用队列可降到O(1). def solution(N,M): from collections import deque que = deque(list(range(1,N+1))) i = 0 while que: i += 1 if i%M == 0: # 如果是M的倍数,移出队列并打印 print(que.popleft() ,end = " ") else: # 否则把队首放到队尾 que.append(que.popleft()) N,M = [int(i) for i in input().split()] solution(N,M)
C语言写的,想法是将人数编号放进一个数组,然后在循环里遍历数组,
check到第M个人就把他的编号打印,并把数组里他的编号置零,当遍历到数组尾部时初始化下标
继续从1号开始。每次遍历都if判断编号是否为0,为0就跳过不计入check。最后是每打印一个编号
就count+1,在打印完所有人后判断count的值跳出循环
void solution(int N, int M){
// TODO Write your code here
int member[N];
for(int i = 1; i <= N; i++)
{
member[i-1] = i;
}
int check = 0;
int count = 0;
for(int i = 1; i <= N; i++)
{
if(count == N) break;
if(member[i-1] != 0){
check++;
if(check == M){
printf("%d ", member[i-1]);
count++;
member[i-1] = 0;
check = 0;
}
}
if(i == N) i = 0;
}
}
function solution(n, m) {
let person = {};
for (let i = 1; i <= n; i++) {
person[i] = i;
}
let res = [];
while (res.length !== n) {
// 找到此时最末尾的数值
let max = Math.max(...Object.values(person));
// 还有多少人没有出去
// 遍历查找谁符合要求
for (let item in person) {
if (person[item] % m === 0) {
res.push(Number(item));
delete person[item]; // 移除队列
}
}
for (let item in person) {
person[item] = max + 1;
max++;
}
}
return res;
} import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int key = sc.nextInt();
sc.close();
int[] orderNo = getOrderNo(n, key);
String s = "";
for (int i = 0; i < orderNo.length; i++) {
s += orderNo[i] + " ";
}
System.out.println(s);
}
public static int[] getOrderNo(int n, int key) {
List<Integer> list = new ArrayList<>(n); // 构建链表
for (int i = 0; i < n; i++) list.add(i + 1);
int[] order = new int[n]; // 构建输出序列
int next = 0; // 指针的下一个位置
int count = 0; // 报数
int flag = 0; // 输出序列的下标
while (list.size() != 0) {
count++;
if (count % key == 0) {
Integer remove = list.remove(next);
order[flag++] = remove.intValue();
} else {
next = (next + 1) % list.size();
}
}
return order;
}
}
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputStr = br.readLine();
int input[] = parseInts(inputStr.split(" "));
String output = solution(input);
System.out.println(output);
}
private static int[] parseInts(String[] strArr) {
if (strArr == null || strArr.length == 0) {
return new int[0];
}
int[] intArr = new int[strArr.length];
for (int i = 0; i < intArr.length; i++) {
intArr[i] = Integer.parseInt(strArr[i]);
}
return intArr;
}
private static String solution(int[] input) {
// TODO Write your code here
SingleCirList list = new SingleCirList();
list.add(input[0]);
list.countStu(1,input[1]);
return list.res.toString();
}
}
//创建一个单循环链表
class SingleCirList{
//创建一个first节点,当前没有编号
Sdu first = null;
StringBuffer res = new StringBuffer();
//添加学生结点构成一个单链表
public void add(int nums){
// 生成辅助结点
Sdu curSdu = null;
//添加学生结点,构成环形链表
for(int i=1; i<= nums; i++){
Sdu sdu = new Sdu(i); //生成一个结点
if(i == 1){//这个判断很重要
first = sdu;
first.next = first;
curSdu = first;
}
curSdu.next = sdu;
sdu.next =first;
curSdu = sdu;
}
}
public void countStu(int start, int countNum){
//创建辅助结点
Sdu helper = first;
while(helper.next != first){
helper = helper.next;
}
for(int i=0; i< start-1; i++){
first = first.next;
helper = helper.next;
}
while(helper != first){
for(int i=1; i<=countNum-1; i++){
first = first.next;
helper = helper.next;
}
res.append(first.no+" ");
first = first.next;
helper.next = first;
}
res.append(first.no+" ");
}
}
// 学生结点
class Sdu{
int no;
Sdu next;
public Sdu(int no){
this.no = no;
}
}
private static String solution(int[] input) {
// TODO Write your code here
int n = input[0], m = input[1], nums = 0, end = n+1;
int[] stud = new int[n];
StringBuilder s = new StringBuilder();
for(int i = 0; i < n; i++){
stud[i] = i+1;
}
while(nums < n){
for(int i = 0; i < n; i++){
if (stud[i] > 0){
if (stud[i] % m == 0){
s.append(i+1).append(" ");
nums++;
stud[i] = -1;
}else {
stud[i] = end++;
}
}
}
}
s.deleteCharAt(s.length() -1);
return s.toString();
} private static String solution(int[] input) {
// TODO Write your code here
int N = input[0];
int M = input[1];
if(N<1 || M<1) return null;
ArrayList<Integer> arr = new ArrayList<Integer>();
StringBuilder sb = new StringBuilder();
for(int i=0;i<N;i++) arr.add(i+1);
int i=0;
while(arr.size()>0){
i += M-1;
if(i>=arr.size()) i=i%arr.size();
sb.append(arr.get(i)).append(" ");
arr.remove(i);
}
return sb.delete(sb.length()-1,sb.length()).toString();
}