算法题(166):占卜DIY

审题:
本题需要我们按照题目中的要求对扑克进行占卜操作,并输出最终的对数

思路:

方法一:直接模拟

本题其实就是一个模拟题,但是如果我们按照题意对扑克堆进行操作,就相当于对数组进行数据头插与尾删了,而我们需要进行的次数是较多的,这样会导致效率低下,且模拟也不是很好进行

方法二:递归+虚模拟

由于题目中只有没翻面的扑克需要参与移动,所以每一堆扑克一共可能移动的就只有四张,我们可以创建一个cnt数组负责记录该行还有多少个未翻动扑克,且如果我们的行数组从下标为1开始插入数据,cnt的值就恰好是该行下一个需要移动的扑克牌的下标。

这里我们第一行的扑克牌中四张都没有翻出来过,所以我们需要移动第四张牌,此时我们直接定位到下标为四的牌就是下一个需要移动的牌

那么我们如何模拟本题?

我们发现每次的操作都是一样的,且在抽取到K之前都是逐层进行的,所以我们可以用递归模拟抽牌和放牌的过程。

dfs功能:完成取牌和放牌动作

结合cnt数组后逻辑为:将第x行的最后一张牌抽取出来,对应行的cnt--,继续对抽出来的牌进行dfs

解题:
 

#include<iostream>
using namespace std;
const int N = 14;
const int n = 14, m = 5;
int a[n][m];//存放初始扑克的数组
int cnt[N];//记录每一行未被翻看的扑克数
void dfs(int x)
{
	if (x == 13) return;
	int num = a[x][cnt[x]];
	cnt[x]--;
	dfs(num);
}
int main()
{
	//数据录入
	for (int i = 1; i <= n - 1; i++)
	{
		cnt[i] = 4;
		for (int j = 1; j <= m - 1; j++)
		{
			char c;
			cin >> c;
			if (c >= '2' && c <= '9') a[i][j] = c - '0';
			else if (c == 'A') a[i][j] = 1;
			else if (c == '0') a[i][j] = 10;
			else if (c == 'J') a[i][j] = 11;
			else if (c == 'Q') a[i][j] = 12;
			else if (c == 'K') a[i][j] = 13;
		}
	}
	//游戏模拟
	for (int i = 1; i <= m - 1; i++)
	{
		dfs(a[13][i]);
	}
	//统计对数
	int answer = 0;
	for (int i = 1; i <= N - 1; i++)
	{
		if (cnt[i] == 0)
		{
			answer++;
		}
	}
	cout << answer << endl;
	return 0;
}

1.由于生命牌有四张,所以我们的初始dfs需要进行四次。

2.dfs的结束条件就是抽到死神牌K的时候,直接返回即可

3.最终cnt中若没有未翻转的牌,说明该牌堆含有一对,即cnt[i]值为0时说明第i行含有一对,answer++

P10457 占卜DIY - 洛谷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值