这一题要求划分的block最多,所以从左往右遍历,只要当前一段的B and W符合ratio,划分成一个block即可。测试数据可能会有多个相连的B or W。如果当前位置W个数>0,可以算出需要多少B,如果个数不够,就看下一个位置能否补充足够的B。如果当前B的个数超出了需求量,一定无法保证ratio。如果当前位置B个数>0,可以算出需要多少W。这两种情况都需要判断,当both B,W>0时,可能只符合其中一种。
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
using namespace std;
//CERC 2014 Problem I Bricks
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
int T;
int n;
long long ans;
pair<long long,char>line[maxn];
long long cntw;
long long cntb;
pair<long long,long long>rat;
long long quickgcd(long long a,long long b)
{
if(a==0) return b;
if(b==0) return a;
if(!(a&1)&&!(b&1)) return quickgcd(a>>1,b>>1)<<1;
else if(!(b&1)) return quickgcd(a,b>>1);
else if(!(a&1)) return quickgcd(a>>1,b);
else return quickgcd(abs(a-b),min(a,b));
}
void solve()
{
long long w=0;
long long b=0;
for(int i=0;i<n;i++)
{
if(line[i].second=='W') w+=line[i].first;
else if(line[i].second=='B') b+=line[i].first;
//cout<<w<<" "<<b<<endl;
if(w>0&&w%rat.first==0)
{
int tmp=w/rat.first*rat.second;
if(b<=tmp)// continue; should not continue if b>tmp, might be applicable for the next if
{
if(b==tmp)
{
ans++;
w=0;
b=0;
continue;
}
tmp-=b;
if(line[i+1].second=='B'&&line[i+1].first>=tmp)
{
line[i+1].first-=tmp;
ans++;
w=0;
b=0;
continue;
}
}
}
if(b>0&&b%rat.second==0)//should consider two if, might satisfy the second if only when both b,w>0
{
int tmp=b/rat.second*rat.first;
if(w<=tmp) //continue;
{
if(w==tmp)
{
ans++;
w=0;
b=0;
continue;
}
tmp-=w;
if(line[i+1].second=='W'&&line[i+1].first>=tmp)
{
line[i+1].first-=tmp;
ans++;
w=0;
b=0;
continue;
}
}
}
}
}
int main()
{
freopen("all.in","r",stdin);
freopen("myall.out","w",stdout);
//freopen("input.txt","r",stdin);
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
scanf("%d",&n);
memset(line,0,sizeof(line));
cntw=0;
cntb=0;
ans=0;
long long cnt=0;
char brick=' ';
for(int i=0;i<n;i++)
{
scanf("%I64d %c",&cnt,&brick);
line[i]=make_pair(cnt,brick);
if(brick=='W') cntw+=cnt;
else if(brick=='B') cntb+=cnt;
}
if(cntw==0)
{
//rat=make_pair(0,1);
ans=cntb;
}
else if(cntb==0)
{
//rat=make_pair(1,0);
ans=cntw;
}
else
{
int d=quickgcd(cntw,cntb);
rat=make_pair(cntw/d,cntb/d);
solve();
}
// if(ca==13797)
// {
// cout<<n<<endl;
// for(int i=0;i<n;i++)
// {
// cout<<line[i].first<<" "<<line[i].second<<endl;
// }
// }
//printf("Case #%d: %I64d\n",ca,ans);
printf("%I64d\n",ans);
}
}