玩扑克游戏

该文章讨论了一种扑克牌洗牌问题,通过每次将最上方的牌移动到底部并输出下一张牌,来寻找原始序列。作者使用队列模拟洗牌过程,通过倒推找到每张牌在洗牌前的位置,从而得出原始序列。代码示例中展示了如何利用C++实现这一算法。
摘要由CSDN通过智能技术生成

玩扑克

题目链接
https://www.luogu.com.cn/problem/P2021

题意

将n张扑克牌经过“每次把最上方的牌放在牌底,然后把下一张扑克牌进行输出”的洗牌操作后,最后输出洗好的为1-n序列的扑克牌,求该扑克牌的原序列。

思路

  1. 可以先利用案例给出的输出模拟一下如何走到洗好后的牌的序列,找到洗牌前后每个牌数下标(索引)的变换规律
  2. 利用1-n进行倒推,将1-n看成是洗牌前的序列,使用抽最上面的牌到最下面,下一张出牌的规则推出最后输出的牌的序列,此时的洗牌前后的下标(索引)的变换规律和刚才的规律是一致的。
  3. 可以发现洗牌后的序列对应的就是洗牌前的牌数

坑点

  1. 无,就是绕
实现步骤
  1. 利用队列——先进先出
  2. 定义两个数组,一个数组a[i]储存洗牌后的牌,一个数组b[i]储存洗牌前的牌
  3. 定义队列q,将1-n使用队列的方法进行入队,再将第一个元素放到队列q的末尾,并将其所在的初始位置删除,此时2就是第一个数(定义一个m,使其初始值为1,每次将前面的牌抽到牌底后,m就+1,得到的值也就是此时队列的第一个值)。在这里插入图片描述
代码
 #include <bits/stdc++.h>
using namespace std;
int a[1000010],b[1000010];
int main()
{
	queue<int> q;
	int n;
	int m=1;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		q.push(i);
	}
	while(!q.empty())
	{
		q.push(q.front());
		q.pop();
		a[m++]=q.front();
		q.pop();
	}
	for(int i=1;i<=n;i++)
	{
		b[a[i]]=i;
	}
	for(int i=1;i<=n;i++)
	{
		cout<<b[i]<<" ";
	}
	return 0;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值