SRM 650 DIV1 Easy - TaroFillingAStringDiv1 (○)

問題


http://community.topcoder.com/stat?c=problem_statement&pm=13669&rd=16314

・AとBから成る文字列を作りたい。
・ただし、i番目の文字はAかBか決まっており、最初にその情報が与えられる。
・また、できるだけAとBが連続しているようにはしたくない。
・上記の情報が与えられるとき、できるだけAとBが連続しないような文字列の場合の数を
 求める。

解き方


・まず、できるだけAとBが連続しないような文字列を求める。
 与えられた情報の位置でソートし、それぞれの間について考える。
 このとき、それぞれのスペースの数+両端のAかBの一致か不一致かによって
 AとBがひとつも連続しないか、そうでないかがわかる。

・次に、そのような場合の数を求める。
・AとBが連続しないようなケースの場合は1通りしか置き方はない。
・AとBが連続するようなケースは、スペースの数だけ場合の数が存在する。

・最後にそれぞれのスペースについての積をとってあげれば答えになる。

コード


using namespace std;

#define all(c) (c).begin(),(c).end()
#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()

int MOD=1000000007;

class TaroFillingAStringDiv1 {

public: int getNumber(int N, vector<int> position, string value) {
int n=position.size();
vector<pair<int,char> > p;
FORE(i,0,n)p.push_back(make_pair(position[i],value[i]));
sort(all(p));

long long ret=1LL;
FORE(i,0,n-1){
int cur=p[i+1].first-p[i].first;
if((cur+(p[i].second!=p[i+1].second))%2)ret=(ret*cur)%MOD;
}
return ret;
}

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