CCF CSP 202109-4 收集卡牌

定义存储结构

结构体:卡牌抽取状态,层数(抽取次数),概率积

定义一个队列,模拟树的层次遍历过程

输入

读入卡牌总数n和硬币k换卡牌数

读入卡牌获得概率

利用队列模拟n叉树的层次遍历

每一个出队的结点

  • 判断是否完成卡牌抽取
  • 若完成,计算概率积,并累计求和
  • 若未完成,继续抽牌,生成子节点,计算概率积,并把子节点入队列

队列为空(遍历结束),输出结果

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
double p[16];//卡牌数n小于等于16,对应的概率数也小于等于16 
int n,k;
struct node{
	int state;//卡牌抽取状态[本质上是一个向量,某位为1,表示抽取到该位的牌] 
	int level;//层数(抽取次数) 
	double p;//概率积 
}; 
int main(){
	scanf("%d%d",&n,&k);//读入卡牌总数n和硬币k换卡牌数
	for(int i=0;i<n;i++) scanf("%lf",p+i);//获得第i种卡牌的概率为p[i-1]
	double ans = 0;//记录期望抽卡次数
	
	node nodecur,nodechild;
	queue<node> q;//定义一个队列,模拟树的层次遍历过程
	
	//初试化根节点 
	nodecur.state = 0;
	nodecur.level = 0;
	nodecur.p = 1;
	//开始n叉树的层次遍历 
	q.push(nodecur); 
	while(!q.empty()){
		nodecur = q.front();
		q.pop();
		int cnt = 0;//记录抽取到的不同种类的牌数
		for(int i=0;i<n;i++)
			if((nodecur.state>>i)&1) cnt++;
		//nodecur.level-cnt为硬币的个数 
		if(cnt+(nodecur.level-cnt)/k>=n){
			ans = ans += nodecur.p * nodecur.level; //累加概率积*层数 
			continue;//此时,不需要生成子节点,直接跳过,原因在于已经符合条件,不需要继续抽牌 
		}
		for(int i=0;i<n;i++){//生成子节点 
			nodechild.p = nodecur.p*p[i];//计算子节点的概率积 
			nodechild.state = nodecur.state|(1<<(n-i-1));
			nodechild.level = nodecur.level + 1;
			q.push(nodechild);//将子节点入队 
		}
	}
	printf("%.10lf\n",ans);//题目样例2保留到了小数点后的第10位 
	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值