Description
给出一个只含有’W’和’B’的字符串,把这个串划分成多段,使得每段’W’和’R’的比例都相同的,问最多能划分多少段?输入给出的是某字符接下来有多少个。
Solution
贪心的想,最优划分每段的比例一定是整个字符串的比例(想想特殊情况和一般情况)。
然后直接统计即可。
如果相同的合并代码量可以降低一点。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100010
using namespace std;
int t[2],tt[2];
int b[N][2],c[N][2],tot=0;
int gcd(int x,int y)
{
int z;
while(x%y!=0)
{
z=x%y;
x=y;
y=z;
}
return y;
}
int main()
{
freopen("silly.in","r",stdin);
freopen("silly.out","w",stdout);
int T;
cin>>T;
while(T--)
{
int n;
scanf("%d",&n);
t[0]=t[1]=0;
fo(i,1,n)
{
int x;
char ch;
scanf("%d %c",&x,&ch);
b[i][0]=(ch=='B');
b[i][1]=x;
t[b[i][0]]+=x;
}
tot=0;
if(!t[0] || !t[1])
{
if(t[0]) printf("%d\n",t[0]);
else printf("%d\n",t[1]);
continue;
}
int gc=gcd(t[0],t[1]);
t[0]/=gc,t[1]/=gc;
fo(i,1,n)
if(b[i][0]!=b[i-1][0] || i==1)
{
tot++;
c[tot][0]=b[i][0];
c[tot][1]=b[i][1];
}
else c[tot][1]+=b[i][1];
int ans=0;
tt[0]=tt[1]=0;
tt[c[1][0]]+=c[1][1];
fo(i,2,tot)
{
if(!tt[0] && !tt[1])
{
tt[c[i][0]]+=c[i][1];
continue;
}
if(c[i][0] && tt[0]%t[0]==0)
{
int p=tt[0]/t[0]*t[1]-tt[1];
if(p<=c[i][1] && p>0)
{
ans++;
tt[0]=0;
tt[1]=c[i][1]-p;
}
else tt[c[i][0]]+=c[i][1];
}
else if(!c[i][0] && tt[1]%t[1]==0)
{
int p=tt[1]/t[1]*t[0]-tt[0];
if(p<=c[i][1] && p>0)
{
ans++;
tt[1]=0;
tt[0]=c[i][1]-p;
}
else tt[c[i][0]]+=c[i][1];
}
else tt[c[i][0]]+=c[i][1];
}
printf("%d\n",ans);
}
}