您的位置:首页 > 其它

Gym - 100543I Bricks 模拟

2017-08-27 11:12 495 查看
题目链接:点击打开链接

题目大意:给你一段序列,要求你将这个序列,分成每一段B和W比率都相等的块,输出分成的块数。

代码参考:@队友 Vectorhr

这个博客好像传不了图片,谁能教教我,我还没搞明白……



AC代码:

/*
2017年8月27日11:10:06
Gym - 100543I
AC
加入了快读 速度更快
*/
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll n,k,tb,tw,nb,nw,sb,sw,ans;

void read(int &x)
{
char ch;
for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar());
x = 0;
for (; ch >= '0' && ch <= '9'; ch = getchar())
x = x * 10 + ch - '0';
}
void read(long long &x)
{
char ch;
for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar());
x = 0;
for (; ch >= '0' && ch <= '9'; ch = getchar())
x = x * 10 + ch - '0';
}
void read(char &c)
{
char ch;
for (ch = getchar(); ch != 'B' && ch != 'W'; ch = getchar());
c = ch;
}

ll gcd(ll x, ll y)
{
return y ? gcd(y, x % y) : x;
}
struct node{
int k;
char c;
}a[maxn];

void solve(){
//tot_b,tot_w
tb=tw=0;
read(n);
//	scanf("%I64d",&n);
for(int i=1;i<=n;i++){
read(a[i].k);
read(a[i].c);
//	scanf("%I64d %c",&a[i].k,&a[i].c);
if(a[i].c=='W') tw+=a[i].k;
else if(a[i].c=='B') tb+=a[i].k;
}
if(!tw||!tb) printf("%I64d\n",tb+tw);
else if(gcd(tb,tw)==1) printf("1\n");
else{
ll g=gcd(tb,tw);
//ll sb,sw;//simple b w;
if(g!=1) sb=tb/g,sw=tw/g;
//每一块中的num_b  num_w
nb=nw=ans=0;
for(int i=1;i<=n;i++){
if(a[i].c=='B'){
//核心代码,如果看不懂,把这个化成分数式子来看,
if((sb*nw)%sw==0&&(sb*nw)>=sw&&(sb*nw)>=(sw*nb)&&(nb+a[i].k)*sw>=(nw*sb)){
nb=a[i].k-sb*nw/sw+nb;
nw=0;
ans++;
}
else{
nb+=a[i].k;
}
}
else if(a[i].c=='W'){
if(sw*nb%sb==0&&sw*nb>=sb&&(sb*nw)<=(sw*nb)&&(nb*sw)<=(sb*(nw+a[i].k))){
nw=a[i].k-sw*nb/sb+nw;
nb=0;
ans++;
}
else{
nw+=a[i].k;
}
}
} printf("%I64d\n",ans);
}
}

int main(){
int t;
//scanf("%I64d",&t);
read(t);
while(t--){
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: