对于一副扑克牌,我们有多种不同的洗牌方式。一种方法是从中间某个位置分成两半,然后相交换,我们称之为移位(shift)。比如原来的次序是123456,从第4个位置交换,结果就是561234。这个方式其实就是数组的循环移位,为了多次进行这个操作,必须使用一种尽可能快的方法来编程实现。在本题目中,还引入另外一种洗牌方式,就是把前一半(如果总数是奇数,就是(n-1)/2)牌翻转过来,这种操作称之为翻转(flip)。在前面shift操作的结果上进行flip,结果就是165234。当然,如果是实际的扑克牌,直接翻转会造成正反面混在一起的,我们就不管那么多了。
给定n张牌,初始次序为从1到n,经过若干次的shift和flip操作后,结果会是什么样?
思路
剑指 offer 例题, 三次 reverse. Leetcode 3.5 出了个新题, 和这道类似
代码
#include#include using namespace std;int card[2000];int ops[2000];int n, k;void myReverse(int st, int ed) { while(st < ed) { swap(card[st], card[ed]); st ++; ed --; }}void shift(int x) { myReverse(1, x); myReverse(x+1, n); myReverse(1, n);}void flip() { myReverse(1, n/2);}int main() { while(scanf("%d%d", &n, &k) != EOF && n != 0) { for(int i = 1; i <= n; i ++) card[i] = i; for(int i = 0; i < k; i ++) scanf("%d", ops+i); for(int i = 0; i < k; i ++) { int x = ops[i]; shift(x); flip(); } for(int i = 1; i <= n; i ++) printf("%d ", card[i]); printf("\n"); } return 0;}