题目描述:
洗牌在生活中十分常见,现在需要写一个程序模拟洗牌的过程。 现在需要洗2n张牌,从上到下依次是第1张,第2张,第3张一直到第2n张。首先,我们把这2n张牌分成两堆,左手拿着第1张到第n张(上半堆),右手拿着第n + 1张到第2n张(下半堆)。接着就开始洗牌的过程,先放下右手的最后一张牌,再放下左手的最后一张牌,接着放下右手的倒数第二张牌,再放下左手的倒数第二张牌,直到最后放下左手的第一张牌。接着把牌合并起来就可以了。 例如有6张牌,最开始牌的序列是1, 2, 3, 4, 5, 6。首先分成两组,左手拿着1, 2, 3;右手拿着4, 5, 6。在洗牌过程中按顺序放下了6, 3, 5, 2, 4, 1。把这六张牌再次合成一组牌之后,我们按照从上往下的顺序看这组牌,就变成了序列1, 4, 2, 5, 3, 6。 现在给出一个原始牌组,请输出这副牌洗牌k次之后从上往下的序列。
输入描述 :
第一行一个数T(T ≤ 100),表示数据组数。对于每组数据,第一行两个数n, k(1 ≤ n, k ≤ 100),接下来一行有2n个数a1, a2, ..., a2n(1 ≤ ai ≤ 1000000000)。表示原始牌组从上到下的序列。
输出描述 :
对于每组数据,输出一行,最终的序列。数字之间用空格隔开,不要在行末输出多余的空格。
输入例子1 :
3 3 1 1 2 3 4 5 6 3 2 1 2 3 4 5 6 2 2 1 1 1 1
输出例子1 :
1 4 2 5 3 6 1 5 4 3 2 6 1 1 1 1
解释一下:3表示3组数据,分别为3 1 1 2 3 4 5 6
3 2 1 2 3 4 5 6
2 2 1 1 1 1
每组数据第一数字为n,第二个数据为k,后面的为2n张牌
//后来才发现被他的举例给坑了,其实是一行一行数据输入的
解题思路:
方案一:
将输入的数据按照洗牌规则洗k次
方案二:
将输入数据的存放位置按洗牌规则洗k次后,确定最后的位置在哪
代码实现:
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 using namespace std; 5 6 int main() 7 { 8 int group; 9 cin >> group; 10 11 vector<int> Res; 12 while (group--) 13 { 14 int n, k; 15 cin >> n >> k; 16 17 //方法一: 18 //vector<int>v1, v2; 19 //vector<int>vv(n * 2); 20 //for (int i = 0; i < 2 * n; ++i) 21 //{ 22 // int a; 23 // cin >> a; 24 // if (i < n) 25 // v1.push_back(a);//左边的一组 26 // else 27 // v2.push_back(a);//右边的一组 28 //} 29 //while (k--) 30 //{ 31 // for (int nn = 0, mm = 0; nn < n * 2; ++mm) 32 // { 33 // vv[nn++] = v1[mm]; 34 // vv[nn++] = v2[mm]; 35 // } 36 // v1.assign(vv.begin(), vv.begin() + n); 37 // v2.assign(vv.begin() + n, vv.end()); 38 //} 39 40 //方法二: 41 vector<int>vv(2 * n); 42 int a; 43 for (int i = 0; i < 2 * n; ++i) 44 { 45 cin >> a; 46 int tmp = i + 1; 47 for (int j = 0; j < k; ++j) 48 if (tmp <= n) 49 tmp = 2 * tmp - 1; 50 else 51 tmp = 2 * (tmp - n); 52 vv[tmp - 1] = a; 53 } 54 55 for (auto b : vv) 56 cout << b << ' '; 57 cout << endl; 58 } 59 return 0; 60 61 }