1042 Shuffling Machine (20 point(s))
题意:
有一个1~54依次编号的序列a(a[i] = i),给出一个Shuffling序列order[],将序列1上的每个值依次换到另一个指定的位置,对于整个序列a,重复n次这样的操作,最后输出a[]所代表的花色和点数
思路:
1.假设已经得到最后洗牌后的结果序列a[]了,思考如何输出最后的花色和点数:
对于每张牌,我们给它唯一的一个标记数字(1-54,按S, H, C, D, J这样的花色顺序来排),
例如一些牌:
编号是1,则其代表S1;
编号是13,则其代表S13;
编号是14, 则其代表H1;
编号是54,则其代表J2......
发现规律了吗?
我们建一个char color[] = {'S','H','C','D','J'},用color[(a[i] - 1) % 13]来获取花色, 输出花色后,如果a[i] > 13就一直a[i] -= 13,最后a[i]的值就是该牌在对应花色下的点数
2.考虑洗牌的过程,a[]用来记录每轮洗牌后的序列,temp[]用来临时存储a[]经一轮洗牌后的序列,order[]用来读输入的移动指令序列,
则对于每轮洗牌的过程,使得temp[i] = a[order[i]], 一轮结束后,再将数组temp[] 赋给 a[], 使得a[] = temp[](vector可以直接互相赋值)
如果不使用vector,也可以使用一个循环(伪代码) for (i = 1 to 54) a[i] = temp[i] 来进行赋值
AC代码:
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 using namespace std; 5 const int MAXA = 54 + 10; 6 const char color[] = {'S', 'H', 'C', 'D', 'J'}; // 使用常量数组 7 vector<int> a, temp, order; // 使用vector以便进行赋值 8 int n; // Shuffling次数 9 void init() { 10 a.resize(MAXA); 11 temp.resize(MAXA); 12 order.resize(MAXA); 13 for (int i = 1; i <= 54; i++) { 14 a[i] = i; 15 scanf("%d", &order[i]); 16 } 17 } 18 void solve() { 19 while (n--) { 20 for (int i = 1; i <= 54; i++) { 21 temp[order[i]] = a[i]; 22 } 23 a = temp; 24 } 25 } 26 void output() { 27 for (int i = 1; i <= 54; i++) { 28 // 将数字序号转化为对应的牌号 29 printf("%c", color[(a[i] - 1) / 13]); 30 while(a[i] > 13) { 31 a[i] -= 13; 32 } 33 printf("%d", a[i]); 34 if (i != 54) printf(" "); 35 } 36 } 37 38 int main() { 39 scanf("%d", &n); 40 init(); 41 solve(); 42 output(); 43 44 return 0; 45 }