《洗牌2》 题解

目录

题目描述

输入描述

输出描述

解析

完整代码


描述

魔术师刘谦要洗牌了,请你写个程序来模拟洗牌的过程。
    洗牌分弹牌和切牌两个操作:
    弹牌——将牌组等分成两份,然后交错相插,如当前牌为1 2 3 4 5 6,现在开始弹牌,先将牌分成1 2 3和4 5 6,然后交错相插,变成1 4 2 5 3 6
    切牌——从牌堆里面拿出连续的一段,然后放到顶端。如当前牌为1 2 3 4 5 6,切完2~5之间的4张牌后变成2 3 4 5 1 6。

输入描述

第一行为两个正整数N和M,N表示牌堆里面有N张牌,M表示共进行M次洗牌的操作。
第二行有N个正整数,代表N张牌上的数字,刘谦用的牌其实就是标有数字的卡片。
接下来M行,每行一个整数或者三个整数。
    如果第一个数为0,那么这一行就这只有一个数,表示弹牌。
    如果第一个数为1,那么后面跟着两个正整数b 和e,表示把b~e这段牌切到顶端。

输出描述

输出M次操作后从第一张开始的每张牌上的数字。相邻两数严格用一个空格隔开,行末不能有多余的空格。

用例输入 1 

10 5
46 21 22 1 20 46 50 7 42 19
1 4 8
1 4 4
1 4 7
0
0

用例输出 1 

46 22 1 21 7 42 20 50 46 19

提示

M≤5,N≤54,且N为偶数
每张牌上标的数为不超过54的正整数,读入一行洗牌指令时应先读一个数,然后判断这个数是0还是1,如果是1则再读2个数。另外你在记录牌的时候可以使用两个以上的数组!

来源

数组问题

兄弟们啊,不是你们c++学不会,而是个别老师他教不对啊。

来,就这数组题你看着懵不懵,懵不懵!

看看老高平时是怎么教我的:

首先要理解题目里的“弹牌”和“切牌”,然后就可以一步步模拟了。

当然,写个自定义函数比较好。

先写切牌,定义如下:

  切牌——从牌堆里面拿出连续的一段,然后放到顶端。如当前牌为1 2 3 4 5 6,切完2~5之间的4张牌后变成2 3 4 5 1 6。

找出输入里给你的那一段数切到前面,肯定是要定义两个数组;把这一段放进b数组里不就是顶端了吗?

    int j=1;
    for(int i=x;i<=y;i++)b[j++]=a[i];

接下来,也是继续存数组剩余的数;

for(int i=1;i<=n;i++)if(i<x||i>y) b[j++]=a[i];//如果不等于x到y的那一段数,就存进去

然后记得存回来:

for(int i=1;i<=n;i++) a[i]=b[i];

接着是弹牌,定义如下:

弹牌——将牌组等分成两份,然后交错相插,如当前牌为1 2 3 4 5 6,现在开始弹牌,先将牌分成1 2 3和4 5 6,然后交错相插,变成1 4 2 5 3 6

啊?这不是洗牌一吗?但也不完全是。

将数组a的前半部分和后半部分交换。函数内部,使用两个辅助数组bc分别存储前半部分和后半部分的元素,然后将它们交换放回数组a中:

int j=1;
    for(int i=1;i<=n;i++){
        if(i<=n/2)b[i]=a[i];
        else c[j++]=a[i];}
    j=1;
    for(int i=1;i<=n/2;i++){
        a[j++]=b[i];
        a[j]=c[i];
        j++;}

好了,现在就剩输入了,但是输入也是要稍微注意一下他的条件:

cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=m;i++){
        int z,xx,yy;
        cin>>z;
        if(z){
            cin>>xx>>yy;
            qp(xx,yy);}
        else tp();}

输出:

for(int i=1;i<=n;i++)cout<<a[i]<<" ";

结束了!

对了,忘说了一句话:

要想c++成绩好,就来jiabei小课堂

下面出示代码:

#include <bits/stdc++.h>
using namespace std;
int n,m,a[1001],b[1001],c[1001];
void qp(int x,int y){
    int j=1;
    for(int i=x;i<=y;i++)b[j++]=a[i];
    for(int i=1;i<=n;i++)if(i<x||i>y) b[j++]=a[i];
    for(int i=1;i<=n;i++) a[i]=b[i];
    return ;}
void tp(){
    int j=1;
    for(int i=1;i<=n;i++){
        if(i<=n/2)b[i]=a[i];
        else c[j++]=a[i];}
    j=1;
    for(int i=1;i<=n/2;i++){
        a[j++]=b[i];
        a[j]=c[i];
        j++;}
    return ;}
int main(){
	cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=m;i++){
        int z,xx,yy;
        cin>>z;
        if(z){
            cin>>xx>>yy;
            qp(xx,yy);}
        else tp();}
    for(int i=1;i<=n;i++)cout<<a[i]<<" ";
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值