時間限制: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,判斷奇偶,就能知道。
而且題目本身好像也說了如果是整數就不用輸出小數形式了。