练习:洗牌问题

有54张牌,牌面分别为2、3、4、5、6、7、8、9、10、J、K、A、W.其中W有2张,其包含两种花色,分别为red和black,其余牌面每种均有4张,包含四种花色,分别为heart,spade,club,diamond.接下来执行洗牌操作,将牌改变到指定位置。例如有
5张牌且排列顺序依次为: heart-3. spade-K. club-10. diamond-A. red-W, 给定洗牌操作的序列:
{4,2,5,3,1},即把heart-3放到4号位、spade-K放到2号位、club-10放到5号位、diamond-A
放到3号位、red-W放到1号位,于是排序就变成了red-W. spade-k,diamond-A, heart-3,
club-10.如果要将上面的洗牌操作执行第2次,则最后的洗牌结果为club-10,spade-K,heart-3,red-w,diamond-A。
输入格式
第一行给出正整数N(1<N<54)表示纸牌的数量。随后N行表示N张牌的初始排列信息,信息包括牌面和花色,以空格间隔。
接下来一行给出一个正整数K(之100),表示洗牌操作次数;最后一行给出洗牌操作序列,包含N个正整数,正整数取值范围在1到54之间,以空格间隔。
输出格式
输出N行,给出N张牌的最后排列结果,每行给出一张牌的牌面和花色,以空格间隔。
输入样例
5
3 heart
K spade
10 club
A diamond
w red
2
4 2 5 3 1
输出样例
10 club
K spade
3 heart
w red
A diamond
——————————————————————————————————————————————————————————————————————————————————————

方法一:直接对牌进行交换位置,再按顺序(1,2,3……)依次输出。(但很复杂)
方法二:不改变原先牌的顺序,但是输出的顺序是特定的顺序
(n次交换后的得到的顺序)

采用方法二
用二维数组接收最初的牌

因为不是两两对应位置互换,而是将各个数放置于特定的位置
所以要另外创建一个临时数组b,一次洗牌完后将排序结果(b中存放的数组)重新赋值回a,之后重复m次,完成洗牌后,a中的数据就是最后输出时对应的顺序


 

#include<stdio.h>
int main()
{
	int n,i,j,k,m,a[54]={0},b[54]={0},s[54]={0};
	scanf("%d\n",&n);
	char c[54][10]={0};
	for(i=0;i<n;i++)
		gets(c[i]);
	scanf("%d",&m);
	for(i=0;i<n;i++)
	{
		scanf("%d",&s[i]);
		a[i]=i+1; 
	}	
	/*
	a[i]中存放的顺序是初始顺序,对应的数字代表对应的牌 
	s[i]中存放的洗牌序列,每次洗牌时对应的洗牌序列时不变的,所以需要将洗牌序列进行存储,以供洗牌时数组下标的更改 
	b[i]为中间数组 
	*/
	for(i=0;i<m;i++)
	{
		for(j=0;j<n;j++)
		{
			b[s[j]-1]=a[j];//洗牌:把值a[j]存储到b数组下标为s[j]-1的位置处 
		}
		for(j=0;j<n;j++)
		{
			a[j]=b[j];
		}
	}
	 for(i=0;i<n;i++)
	 {
	 	puts(c[a[i]-1]);//puts自动换行 
	 }
	return 0;
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值