扑克牌游戏_题解

【题解提供者】吴立强

解法

思路

本题其实是改版的【约瑟夫环】问题,本质上还是依次找到某个位置的人,然后将这个人踢出队伍。

环状结构可以使用循环取模的方式来模拟(也就是代码中 p o s pos pos 的运行逻辑)。

踢出操作可以使用标记数组(也就是代码中的 v i s vis vis),false 代表没有被踢出,true 代表已经被踢出。

代码展示

#include <iostream>
using namespace std;

const int N = 109;
bool vis[N];
int a[N];

void solved() {
	int n, m;  cin >> n >> m;
	/// 假设所有位置都没有被确定
	for(int i = 0; i < n; i ++) vis[i] = false;
	/// 以下两行用于标记第一个位置的牌是 1
	a[0] = 1;
	vis[0] = true;
	/// 现在在第 pos 张牌的位置,已经把 sum 张牌放在牌堆底了
	int pos = 0, sum = 0;
	/// 寻找编号 2 至编号 n 的牌在原本牌堆中的位置
	for(int i = 2; i <= n; i ++) {
		/// 找到没有被使用的第 m+1 个位置,就是当前牌被安置的位置
		while(sum <= m) {
			/// 找到下一个位置
			pos = (pos + 1) % n;
			/// 计算当前是第几个未被使用位置(已使用不算位置)
			sum += (vis[pos] == false);
		}
		/// 标记当前位置已使用、记录当前位置的牌编号、将 sum 置 0
		vis[pos] = true;
		a[pos] = i;
		sum = 0;
	}
	for(int i = 0; i < n; i ++) cout << a[i] << ' ';
	cout << endl;
}
int main() {
	int t;
	cin >> t;
	while(t --) {
        /// 分别完成 t 个子问题
		solved();
	}
  return 0;
}

算法分析

本程序具体时间复杂度难以推出,但是可以确定其时间复杂度上限 O ( t × n × n ) O(t \times n\times n) O(t×n×n)(因为 m ≤ n m\le n mn 所以单次查找位置最多扫描 n n n 个位置)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值