I - Bricks ( 贪心模拟 )
题意:给一个字符串,1B 3W 2B 代表BWWWBB。 问这个字符串最多能分成几部分,使得每一部分B和W的比例和总串一样。
思路:贪心思想,从头开始往后分, 满足一个公式, 我们for循环每一块的时候判断要么nowb增加,要么noww增加,左边的值是固定的,这样就可以判断如果在增加前不符合条件,在增加的过程中等于了条件那么就是可以的, 注意用乘法来模拟。具体看代码。
注意:在求want的时候,没判断sumb*noww/sumw是不是整数WA了一个小时。。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
struct node {
char str;
ll date;
} a[maxn];
ll n;
int main()
{
ll listt,i;
scanf("%lld",&listt);
while ( listt-- ) {
scanf("%lld",&n);
ll sumb=0,sumw=0;
for ( i=0; i<n; i++ ) {
scanf("%lld %c",&a[i].date, &a[i].str);
if ( a[i].str=='B' ) sumb += a[i].date;
else sumw += a[i].date;
}
if ( sumb==0||sumw==0 ) {
printf("%lld\n",max(sumb,sumw));
continue ;
}
else if ( __gcd(sumb,sumw)==1 ) {
printf("1\n");
continue ;
}
ll tot = sumw+sumb;
ll gcd = __gcd(sumw,sumb);
sumb /= gcd;
sumw /= gcd;
ll nowb=0,noww=0;
ll ans = 0;
for ( i=0; i<n; i++ ) {
if ( a[i].str=='B' ) {
if ( nowb==0&&noww==0 ) nowb += a[i].date;
else {
if ( sumb*noww%sumw==0 && nowb*sumw<sumb*noww && (nowb+a[i].date)*sumw>=sumb*noww ) {
ll want = sumb*noww/sumw - nowb;
ans ++;
nowb = a[i].date-want;
noww = 0;
}
else {
nowb += a[i].date;
}
}
}
else if ( a[i].str=='W' ) {
if ( nowb==0&&noww==0 ) noww += a[i].date;
else {
if ( sumw*nowb%sumb==0 && nowb*sumw>sumb*noww && nowb*sumw<=sumb*(noww+a[i].date) ) {
ll want = sumw*nowb/sumb - noww;
ans ++;
noww = a[i].date-want;
nowb = 0;
}
else {
noww += a[i].date;
}
}
}
}
printf("%lld\n",ans);
}
return 0;
}