B.伤害计算

传送门

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

勇士菜哭武获得了一把新的武器,武器有特殊的伤害计算方式。武器的伤害计算方式由若干个部分的和组成,用+号连接。每一部分可以是一个整数a,或者是一个公式ndx。其中a表示固定伤害a点;ndx表示掷n个x面骰子,伤害是所有骰子点数的和。总伤害是每一部分伤害的和。

比如2d6+1d70+3,表示掷两个6面骰子和一个70面骰子(不一定实际存在70面骰子,可以理解成1到70当中随机选择一个整数),再加上固定伤害3点。

他正准备挑选一把好武器,需要计算新武器的伤害期望值,想让你帮他计算一下。

输入描述:

输入一个字符串,表示伤害计算公式。字符串长度不超过5000,对于每一个部分,1≤a, n, x≤1000。a,n,x都是整数。 

输出描述:

输出一个数,表示伤害的期望值。如果不是整数,小数点后位数保留最少,即最终结果只有可能是整数或者小数点后是.5的形式,如果不是整数,那么保留一位小数。
示例1

输入

1d6+1d70+1d10+6

输出

50.5

思路:

根据+号分割开,然后分类解决。包含 d 的:n*(x+1)/2;不包含 d 的直接 atoi 一下就可以。
注意避免浮点数运算,可以全部都乘 2 然后输出的时候分奇偶判断是否输出.5。
注意输出浮点数的时候,如果有 1000000 之类的数可能会输出成 1e+06 的形式。全部使用
整数计算可以避免此类问题
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>

using namespace std;

int main()
{
	string s;
	cin>>s;
	int ans=0;
	for(int i=0;i<s.length();i++)
	{
		string str="";
		bool flag1=0;//是否有d 
		int idx=0;//计数
		int idxx=0;//d的下标 
		for(int j=i;j<=i+8&&j<s.length();j++)
		{
			if(s[j]=='+') break;
			str+=s[j];
			if(s[j]=='d') 
			{
				flag1=1;
				idxx=idx;
			}
			idx++;
		}
		if(!flag1)
		{
			int num=0;
			int mul=1;
			for(int j=str.length()-1;j>=0;j--)
			{
				num+=(str[j]-'0')*mul;
				mul*=10;
			}
			ans+=num*2;
		 } 
		else 
		{
			int n=0,x=0;
			int mul=1;
			for(int j=idxx-1;j>=0;j--)
			{
				n+=(str[j]-'0')*mul;
				mul*=10;
			}
			mul=1;
			for(int j=str.length()-1;j>=idxx+1;j--)
			{
				x+=((str[j]-'0')*mul);
				mul*=10;
			}
			ans+=(n*(x+1));
		}
		i+=str.length();
	}
	cout<<ans/2;
	if(ans%2) cout<<".5";
	
	
	return 0;
}

说实话,题解中处理浮点数的方式是极好的。针对除2的运算,只有整除和余1的情况,那么最后的答案要么是整数,要么余0.5.只要在之前都乘2,判断奇偶,就能知道。

而且题目本身好像也说了如果是整数就不用输出小数形式了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章