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,判斷奇偶,就能知道。

而且題目本身好像也說了如果是整數就不用輸出小數形式了。

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