2015杭电新生赛1003玩骰子【大型模拟】

9 篇文章 0 订阅

玩骰子

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1197    Accepted Submission(s): 358


Problem Description
  Nias与Ains都特别喜欢玩骰子,而且都自以为比对方玩得更溜。
  终于有一天,他们决定用骰子来一决高下!
  一般的骰子玩法已经不足以体现他们的水平了,于是他们自创了一套玩法来PK:
首先,每人掷3个骰子;之后,可以选择其中一个骰子重新掷(当然也可以放弃这一步),最后,比较投掷结果的大小,结果大的那方获胜,一样的话为平局。
  大小比较规则为:
  三个一样数字的骰子称为三条;两个一样数字的骰子称为对子;只有一个数字的骰子成为散牌。三条>对子>散牌。当双方结果都为三条时,直接比较三条数字的大小;都有对子时,先比较对子数字的大小,若相同,再比较剩下的骰子的数字的大小;都只有散牌时,先比较最大的数字的大小,若相同,再比较次大的数字的大小,还相同,最后比较最小的数字的大小。

  现在Nias已经投了3个骰子,还剩一次机会可以选择其中一个骰子重新投(或不选),而且他已经知道了Ains的最后投掷结果,求Nias获胜的概率有多大。
 

Input
输入数据第一行为一个整数T,表示有T组测试数据。
接下来T行,每行6个1~6的整数,前三个表示Nias第一次的投掷结果,后三个表示Aias最终的投掷结果。
 

Output
请输出Nias获胜的概率,结果保留3位小数,每组输出占一行。
 

Sample Input
  
  
4 2 3 5 3 3 4 3 3 1 2 2 2 6 2 1 5 4 3 1 2 3 4 4 1
 

Sample Output
  
  
0.333 0.167 1.000 0.000
 


很繁琐的模拟题。为了找BUG我学会了对拍...也算是一个收获了

#include <iostream>
#include <cstring>
#include <map>
#include <algorithm>
#include <iomanip>
#include <cmath>
using namespace std;

int num1[10]={0},num2[10]={0};
int size2=0;
int now[3];
bool has_won()
{
	memset(num1,0,sizeof num1);
	for(int i=0 ; i<3 ; ++i)num1[now[i]]++;
	int size1=0;//条子数, 
	for(int i=1 ; i<=6 ; ++i)
	{
		size1=max(num1[i],size1);
	}
	if(size1>size2)return 1;
	else if(size1<size2)return 0;
	else
	{
		if(size1==1 || size1==3)
		{
			for(int i=6 ; i>=0 ; --i)
			{
				if(num1[i] && num1[i]==num2[i])
				{
					if(size1==3)return 0;
					else continue;
				}
				if(num1[i])return 1;
				if(num2[i])return 0;
			}
			return 0;
		}
		else if(size1==2)
		{
			int a=0,b=0;
			for(int i=6 ; i>=0 ; --i)
			{
				if(num1[i]==2)
					a=i;
				if(num2[i]==2)
					b=i;
			}
			if(a>b)return 1;
			else if(a<b)return 0;
			else
			{
				for(int i=6 ; i>=0 ; --i)
				{
					if(num1[i]!=2 || num2[i]!=2)
					{
						if(num1[i] && num1[i]!=num2[i])return 1;
						if(num2[i])return 0;
					}
				}
			}
		}
	}
	return 1;
}
int main(void)
{
	cin.tie(0);ios::sync_with_stdio(0);
	int T;
	cin>>T;
	cout<<fixed<<setprecision(3);
	while(T--)
	{
		memset(num2,0,sizeof num2);
		size2=0;
		cin>>now[0]>>now[1]>>now[2];
		for(int i=0 ; i<3 ; ++i)
		{
			int t;
			cin>>t;
			num2[t]++;
		}
		for(int i=1 ; i<=6 ; ++i)
		{
			size2=max(num2[i],size2);
		}
		double ans=0;
		if(has_won())cout<<"1.000"<<"\n";
		else
		{
			int ori=now[0];
			for(int k=0 ; k<3 ; ++k)
			{
				int a=0,b=0;
				ori=now[k];
				for(int i=1 ; i<=6 ; ++i)
				{
					b++;
					now[k]=i;
					//cout<<"try:";
					//for(int i=0 ; i<3 ; ++i)cout<<now[i]<<" ";
					//cout<<"\n";
					if(has_won())
					{
						//cout<<"passed\n";
						a++;
					}
				}
				if(b!=0)ans=max((double)a/b,ans);
				//cout<<"nowans:"<<ans<<"\n";
				now[k]=ori;
			}
			cout<<ans<<"\n";
		}
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值