A - Yellow Cards
大致题意
两个队伍,给出每个队伍人数,然后罚下每个队伍的人分别需要的黄牌数。问给出一定的黄牌数,能罚下这两队的最多人数和最少人数。
思路
- 最多人数好想,直接贪心的从需要罚下黄牌数少的那个队伍开始罚。
- 最多人数可以直接通过把总的所有的人被罚下的黄牌数都换成一(也就是让每个人都保持差一张被罚下),这样就可以比较剩余的黄牌数和人数之间的大小
//
// main.cpp
// A_贪心模拟
//
// Created by 陈冉飞 on 2019/10/12.
// Copyright © 2019 陈冉飞. All rights reserved.
//
#include <iostream>
using namespace std;
int a1,a2,k1,k2,n,ans1,ans2;
int main(int argc, const char * argv[]) {
scanf("%d%d%d%d%d",&a1,&a2,&k1,&k2,&n);
//算最大
if (k1 < k2) {
if (a1*k1 > n) ans1 += (n/k1);
else ans1 += (a1+ (n-a1*k1)/k2);
}else {
if (a2*k2 > n) ans1 += (n/k2);
else ans1 += (a2+ (n-a2*k2)/k1);
}
// cout<<ans1<<endl;
//算最小 先把每个人都减到就剩一张罚出场,
int tem = max(0,n-(a1*(k1-1)+a2*(k2-1)));
ans2 = min(tem,n);
cout<<ans2<<" "<<ans1<<endl;
return 0;
}
B. The Number of Products
大致题意
给出一串数字,然后求区间乘积为正的区间数和乘积为负的区间数。
思路
- 考虑到区间乘积不是正就是负,可以只算一个然后用n!(总区间数)来减去算出的一个区间数。
- 可以用前缀积来计算
- 可以通过dp扫一遍。dp记录到这个数之前的所有的正数/负数的和
(注意在负数情况的时候neg[i] = pos[i-1]+1,是加上上一位正数的,因为负数改变了正负性)
//
// main.cpp
// B_dp记录
//
// Created by 陈冉飞 on 2019/10/12.
// Copyright © 2019 陈冉飞. All rights reserved.
//
#include <iostream>
using namespace std;
#define maxn 200010
typedef long long ll;
ll n,neg[maxn],pos[maxn],tem,a[maxn],ans1,ans2;
#include <cmath>
int main(int argc, const char * argv[]) {
scanf("%lld",&n);
a[0] = 1;
neg[0] = pos[0] = 0;
for (ll i = 1; i <= n; i++) {
scanf("%lld",&tem);
// a[i] = a[i-1]*(tem/abs(tem));//防止爆掉ll
if (tem>0) {
neg[i] = neg[i-1];
pos[i] = pos[i-1]+1;
}else {
neg[i] = pos[i-1]+1;
pos[i] = neg[i-1];
}
ans1 += neg[i];
ans2 += pos[i];
}
cout<<ans1<<" "<<ans2<<endl;
return 0;
}