解法1:转换成约瑟夫问题:
转换成约瑟夫问题:
我们看这个整个一次过程,就相当于从第一个元素开始,数到第二个元素,把这个第二个元素kill(移除队列)。之后再从这个被kill的元素的下一个元素(这时候已经成了新的队头),又开始数,到第二个又删除……..
那么就出来了:这是一个环内有6个数的约瑟夫环,q = 2的出环问题。
我们要求的,就是原先的队列的各个位置的值,也相当于每一步出队返回的下标,将其的值按照这个下标排列:
我们知道这时候的出队顺序是: 1 2 3 4 5 6
| | | | | |
而约瑟夫环中出队的顺序是: 2 4 6 3 1 5
如上的一一对应关系是:值1在原队列的2号位置,值2在原队列的4号位置,值3在原队列的6号位置.....
得出的结果就是:5 1 4 2 6 3
1
2
3
4
5
6
7
而题目中给出的答案也是这样。
所以我们得出一种比较简单的解题思路:
将1到n重新按照这个规则来排列一边,得到的就是与输出结果对应的出队顺序,可以借此还原先前的队列:
---------------------
原来题主链接:https://blog.csdn.net/tingyun_say/article/details/52344785
import java.util.*;
public class Main {
public static void main(String args[]){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
int k=in.nextInt();
while(k>0){
k--;
int n=in.nextInt();
Queue<Integer> queue=new LinkedList<Integer>();
for(int i=1;i<=n;i++){
queue.offer(i);
}
int res[]=new int[n+1];
int tempres[]=new int[n+1];
int temp1,cnt=1;
while(queue.size()>0){
temp1=queue.poll();
queue.offer(temp1);
temp1=queue.poll();
tempres[cnt++]=temp1;
}
for(int i=1;i<=n;i++){
res[tempres[i]]=i;
}
for(int i=1;i<=n;i++){
if(i==1){
System.out.print(res[i]);
}else{
System.out.print(" "+res[i]);
}
}
System.out.println();
}
}
}
}
解法2:(有选择性的看)这个模拟题看了好久,找到一个大神的解法:
原来题主链接:
首先在队列中依次加入1,2,...n,代表题目描述中A序列的下标,然后模拟题目描述的过程,可以知道第1个会输出2,这就代表着B序列中下标1的元素恰好是A序列中下标2的元素,而我们知道B序列下标1的元素就是“1”,也就是说A序列中下标2的元素是“1”,另开辟一个数组,在数组第2位存下1,再继续模拟,重复以上过程,则这个数组中的元素顺序就是答案要的~
---------------------
import java.util.*;
public class Main {
public static void main(String args[]){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
int k=in.nextInt();
while(k>0){
k--;
int n=in.nextInt();
Queue<Integer> queue=new LinkedList<Integer>();
for(int i=1;i<=n;i++){
queue.offer(i);
}
int res[]=new int[n+1];
int temp1,cnt=1;
while(queue.size()>0){
temp1=queue.poll();
queue.offer(temp1);
temp1=queue.poll();
res[temp1]=cnt++;
}
for(int i=1;i<=n;i++){
if(i==1){
System.out.print(res[i]);
}else{
System.out.print(" "+res[i]);
}
}
System.out.println();
}
}
}
}