PAT-A 1042. Shuffling Machine (20)

题目链接在此

题意理解

本题的最核心是:通过一种操作,将牌的位置改变到指定位置。
例如,有5张牌S3,H5,C1,D13,J2,然后给定操作序列{4,2,5,3,1},因此把S3放到4号位,H5放到2号位,以此类推,C1,D13,J2的位置为5,3,1,得到的最终的序列为{J2,H5,D13,S3,C1}。
现在,需要将这种操作进行n次,求出最后的排列结果。例如上面的例子,在执行第二次操作之后的序列为{C1,H5,S3,J2,D13}。

解题思路

想必读者在将上面的例子自行推演一遍后已经能够清晰的理解题目的意思,这是一道“简单模拟”题,故我们只需要用代码实现这个算法的过程即可。(现在看来几乎所有的题目也都如此,先想到算法,再实现算法,就能够达到解题的目的。)

那么我们就来想办法实现这样的一个算法过程:
1. 首先,我们将54张不同的牌对应到一个整形数组mp中,方便后面的次序交换以及结果输出。
2. 我们定义两个整形数组start和temp,用来存放某一次执行操作前的牌序和执行操作后的牌序。(如样例输入,根据第一步我们知道,S10这张牌的序号为10(初始状态下),当执行一次操作序列后,S10就应该放到54号位置)
3. 我们需要执行n次操作,第一次操作,我们将start中的牌序经过操作序列后的牌序放到temp中,第二次操作,我们将temp中的牌序经过操作序列后的牌序放到start中,以此类推,可根据次数的奇偶性来判断最后应该输出start还是temp中的牌序序列(若n==1,只进行一次操作,则最终序列在temp中;若n==4,需要进行4次操作,则最终序列在start数组中)。

AC代码

#include<stdio.h>

char mp[55][10] = { {""}, {"S1"}, {"S2"}, {"S3"}, {"S4"}, {"S5"}, {"S6"}, {"S7"}, {"S8"}, {"S9"}, {"S10"}, {"S11"}, {"S12"}, {"S13"},
                       {"H1"}, {"H2"}, {"H3"}, {"H4"}, {"H5"}, {"H6"}, {"H7"}, {"H8"}, {"H9"}, {"H10"}, {"H11"}, {"H12"}, {"H13"},
                       {"C1"}, {"C2"}, {"C3"}, {"C4"}, {"C5"}, {"C6"}, {"C7"}, {"C8"}, {"C9"}, {"C10"}, {"C11"}, {"C12"}, {"C13"}, 
                       {"D1"}, {"D2"}, {"D3"}, {"D4"}, {"D5"}, {"D6"}, {"D7"}, {"D8"}, {"D9"}, {"D10"}, {"D11"}, {"D12"}, {"D13"},
                       {"J1"}, {"J2"} };

int main(){

    int n;
    int order[55];
    int start[55], temp[55];

    scanf("%d",&n);
    for(int i = 1; i < 55; i++){
        scanf("%d",&order[i]);
    }

    //初始化start数组
    for(int i = 0 ; i < 55; i++){
        start[i] = i;
    } 

    //开始一遍一遍换顺序(order数组 ) 
    for(int i = 0 ; i < n; i++){  //控制顺序变换次数 

        if( i % 2){ //i是奇数,则start中的顺序放入temp中 
            for(int j = 1 ; j < 55; j++){
                start[ order[j] ] = temp[j];
            }
        } else{
            for(int j = 1 ; j < 55; j++){
                temp[ order[j] ] = start[j];
            }
        }
    }

    for(int i = 1; i < 55; i++){
        if(n%2){ //n是奇数,最后的序列在temp数组,否则在start数组 
            printf("%s",mp[ temp[i] ]);
            if(i < 54){
                printf(" ");
            }
        } else{
            printf("%s",mp[ start[i] ]);
            if(i < 54){
                printf(" ");
            }
        }
    }

    return 0;
} 

《算法笔记》中在这道题的解题思路上大致相同,不同点在于:
1. start和temp数组的分工明确,start数组存的永远是已经经过特定操作后的牌序,这就需要在以上方法将牌序调入temp后,用temp的牌序覆盖掉start数组中的牌序。
2. 没有用一个二维数组(或者指针数组)作为一个mp,只是将五种花色“S,H,C,D,J”存入一个mp,需要输出如S12时,S从mp中经过特定运算取得,12也是经过相关变量的特定运算得到,具体的运算方法读者自行思考,只需要注意每种花色的末尾的临界情况(S13,H13,C13,D13)。

《算法笔记》购买地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值