题目描述
LQX在高老师不在的一天当中发明了一个小游戏:将若干黑色和白色的乒乓球摆成一列。现在他想按顺序(分组时只能按照从左往右的顺序取)将这些乒乓球分成若组,使得每组的白球和黑球的比例相同。
当然,他可以把所有的球直接作为一组,但是那样你就太鄙视LQX的智商了。为了增加难度,他想知道最多能分成多少组,例如,如果用0表示白球,1表示黑球的话,那么:
100011 = 10+0011(样例1,最多分成两组,比例为1:1)
0001110000000001 = 0001+11000000+0001(样例2,最多分成3组,比例为3:1)
LQX在高老师不在的一天当中发明了一个小游戏:将若干黑色和白色的乒乓球摆成一列。现在他想按顺序(分组时只能按照从左往右的顺序取)将这些乒乓球分成若组,使得每组的白球和黑球的比例相同。
当然,他可以把所有的球直接作为一组,但是那样你就太鄙视LQX的智商了。为了增加难度,他想知道最多能分成多少组,例如,如果用0表示白球,1表示黑球的话,那么:
100011 = 10+0011(样例1,最多分成两组,比例为1:1)
0001110000000001 = 0001+11000000+0001(样例2,最多分成3组,比例为3:1)
输入
第一行输入一个整数N,表示将用N行来描述这一列乒乓球。
以下N行,每行包含两个用空格隔开的整数Ki和Ci,Ci只可能是0或1,表示在上一行结束后尾部又有了Ki个颜色为Ci的乒乓球。
注意:连续几行的Ci可能相同。
输出
输出一行一个整数,表示最多能分成的组数。
样例输入
3 1 1 3 0 2 1
样例输出
2
提示
N<=10^5
乒乓球的个数不超过10^9
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; long long n,a[100000],b[100000],ans[100000],sum[100000],maxn; int main() { cin>>n; for(long long i=1;i<=n;i++) { cin>>a[i]>>b[i]; sum[b[i]]+=a[i];//分别统计黑球和白球的个数。 } if(!sum[0])//判断特殊的情况,当某一种球不存在,则答案一定是另一种球的个数。 { cout<<sum[1]; return 0; } if(!sum[1])//判断另一种球,理由如上 { cout<<sum[0]; return 0; } for(long long i=1;i<=n;i++)//贪心 { long long x=b[i];//根据输入,将x变为第一种的球。 long long y; if(x==1)y=0;//如果x为白球,则将y变为黑球,反取 else if(x==0) y=1;//方法同上 if(sum[x]*ans[y]%sum[y]==0)//判断是否除尽,也就是比例是否成立。 { int h=sum[x]*ans[y]/sum[y]-ans[x];//去算少了多少 if(a[i]>=h&&h>=1) { maxn++;//统计有多少种分割方案 } } ans[x]+=a[i];//ans累加 } cout<<maxn; }
这一道题是一道贪心!
从头开始:
首先定义4个数组,不需要二维数组。
ai表示输入时的ki。bi表示输入时的ci。
sum数组表示黑球和白球分别得数量。
ans数组表示一个ki的累加,这样一直寻找成立的比例。
其中 如果一个比例成立,则说明黑球和白球的比例也和这个成立的比例相关。
详细的解在代码里!
#include <cstdio> typedef long long LL; const int MAXN = 111111; int a[MAXN], b[MAXN], s[MAXN], t[MAXN]; int main(){ freopen("ball.in","r",stdin); freopen("ball.out","w",stdout); int n, ans = 0; scanf("%d", &n); for(int i = 0; i < n; ++i){ scanf("%d%d", &a[i], &b[i]); s[b[i]] += a[i]; } if(!s[0] || !s[1]){ printf("%d ", s[0] + s[1]); return 0; } for(int i = 0; i < n; ++i){ int x = b[i], y = b[i] ^ 1; if(s[y] && s[x] * t[y] % s[y] == 0){ int z = s[x] * t[y] / s[y] - t[x]; if(z >= 1 && z <= a[i]) ++ans; } t[x] += a[i]; } printf("%d ", ans); return 0; }
老师的代码。