题目描述:
一副从1到n的牌,每次从牌堆顶取一张放桌子上,再取一张放牌堆底,直到手上没牌,最后桌子上的牌是从1到n有序(从下到上),设计程序,输入n,输出牌堆的顺序数组。
解题思路:
以n=5为例:
如果考虑的是最后桌子上的牌是1,2,3,4,5(从上往下)
也就是说,原先的一张牌,先取出5,然后放入牌底一张;再取出4;然后放入牌底一张;再取出3;然后放入牌底一张;再取出2;然后放入牌底一张;再取出1。使用图示表示为(左边褐色箭头所示):则反演可以得到5 1 4 2 3的初始顺序。
同时,也应该注意到,将5取走后,然后放入牌底一张;就得到的是如图所示的n=4的过程。
所以在过程中我们可以想象,对于我们所预设的最后桌子上的牌是1,2,…,n(从上往下),即取牌顺序为n,n-1,…,2,1
对于任意一个n,n必然在第一张,取走之后,在放入一张在牌堆底部;剩下的牌堆必须抽出n-1,…,2,1,即对于n-1时的情况。
所以求n的情况时,先求出n-1时的情况,他的底部的一张是由n的情况的第二张放去的;所以将n-1的情况的底部放回首部,在在首部放上n就是n的情况的解答。
所以伪代码可以表示为:
solution(n)
list <- solution(n-1)
list.head <- list.tail
delete list.tail
list.head <- n
return list
同时,由于题目要求的是最后桌子上的牌是从1到n有序(从下到上),所以只要在输出的时候将i转为n+1-i输出即可。
代码实现
import java.util.LinkedList;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long n = in.nextLong();
LinkedList<Long> list = soluation(n);
for (Long long1 : list) {
System.out.print(n+1-long1+" ");
}
System.out.println();
in.close();
}
private static LinkedList<Long> soluation(long n) {
if(n==1) {
LinkedList<Long> list = new LinkedList<Long>();
list.add((long) 1);
return list;
}
LinkedList<Long> list = soluation(n-1);
list.addFirst(list.removeLast());
list.addFirst(n);
return list;
}
}