题意:
- 洗一个洗牌程序,牌的初试状况是S1~S13,H1~H13,C1~C13,D1~D13,J1,J2;
- 按照如下规则洗牌:输入一组数,如果位置i的数为j,那么就将牌中第i张牌与第j张牌置换,再根据给定的k决定进行几次洗牌;
- 比如:有五张牌:S3, H5, C1, D13 和 J2 按照{4, 2, 5, 3, 1}洗牌,就会变成J2, H5, D13, S3, C1,比如第一位为4,那么就是将牌中第一张牌S3与第四张牌D13换位,然后依次进行,将这种行为进行两次会得到:C1, H5, S3, J2, D13.(具体进行几次洗牌,根据给定的k来决定)
思路:
- 因为题中牌有花色,如果直接存储字符和数字会很麻烦,所以我们利用一种转换关系来处理,发现每种花色都是13张(除了Joker,但不影响解题),那么我们直接存储牌号k(也就是这张牌在所有牌中的顺序,例如S2是第二张,H1是第十四张),再将花色存储在一个数组mp[]={'S','H','C','D'}中那么用mp[(k-1)/13]就是这张牌对应的花色,那么这张牌对应花色的数字是mp[(k-1)%13+1];(这里太理解的话可以举个例子,例如H1的牌序是14,那么(14)-1/13=1即是红桃H,数字是(14-1)%13+1=1,即得出这张牌是H1);
- 做完第一步我们就知道了牌序可以与每张牌相对应;
- 下一步我们要用一个数组next[]来接收洗牌的序列,然后在定义一个start[],和end[]数组,分别表示洗牌前的牌序和洗牌后的牌序,这样每一次操作都可以把start[]的每一个位置的牌号存放在end[]的对应位置中,再用end[]覆盖start[],这样当操作了K轮之后,数组start[]还是存放了最终的牌序;
注意:
- 末尾的输出不能有空格;
#include<cstdio> const int N = 54; int start[N+1],end[N+1]; int next[N+1]; char mp[5] = {'S','H','C','D','J'}; int main(){ int k; scanf("%d",&k); for(int i=1;i<=N;i++){ scanf("%d",&next[i]); } for(int i=1;i<=N;i++){ start[i] = i; } for(int step=0;step<k;step++){ for(int i=1;i<=N;i++){ end[next[i]] = start[i]; } for(int i=1;i<=N;i++){ start[i] = end[i]; } } for(int i=1;i<=N;i++){ if(i!=1){ printf(" "); } int t = start[i] - 1; printf("%c%d",mp[t/13],t%13+1); } return 0; }