SRM 547 DIV1 Easy - Pillars (復習×○)

問題


http://community.topcoder.com/stat?c=problem_statement&pm=12055&rd=14739

柱が2つ与えられる。柱の間の距離はw。

2つの柱の最大の長さx、yが与えられ、1~x、1~yの間で好きに決めることができる。

最後に、柱のてっぺんをロープで結び、その長さの平均値を求める。

解き方


x、yが10^5のため、全探索で解くことはできない。
2つの柱の差の数は、2つの求め方がある。
1)x、yから計算式を求めて一意に決定
2)xのみ1~xまで変化させ、それぞれに対しとりうる値を区間で求める。

今回は2の方法でコーディングしました。

1つエラーではまった原因としては、iをint型で計算したため数が大きい場合にエラーになってしまいました。
「計算は全て型を一致させる」、という基本を忘れないようにします。

ちなみに1の場合は、長さのとりうる値1-xからy-1までループさせ、
i<=0のときはmin(y,x+i)
i>0のときはmin(x,y-i)分だけその長さが存在することになります。

コード


class Pillars {

public: double getExpectedLength(int w, int x, int y) {
if(x>y)swap(x,y);

double ret=w*x;

for(int len=1;len<=y-1;len++){
int cnt=max(0,min(x,y-len))+max(0,min(x-len,y));
ret+=cnt*sqrt((double)len*len+w*w);
}

return ret/x/y;
}

};



using namespace std;

#define FORE(i,d,e) for(int i=d;i<e;i++)
#define FOR(i,s,e) for (int i = int(s); i != int(e); i++)
#define FORIT(i,c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ISEQ(c) (c).begin(), (c).end()

class Pillars {

public:

double getExpectedLength(int w, long long x, long long y) {
double ret=0;

if(x>y)swap(x,y);

double dp[y];
dp[0]=0;
for(long long i=1;i<y;i++)dp[i]=dp[i-1]+sqrt((double)(w*w+i*i));
for(long long i=1;i<=x;i++)ret+=dp[i-1]+dp[y-i]+w;

return ret/x/y;

}

};
このエントリーをはてなブックマークに追加