E. Blackslex and Girls

E. Blackslex and Girlshttps://codeforces.com/contest/2179/problem/E

题目简述:

有n个政治选区,每个选取有两个党派(A,B)竞争,给定一个只含10的字符串s,代表每个选区的竞争结果,如果si=0,代表A人数>B人数,如果si=1,代表A人数<B人数,同时给定A的总人数为x,B的总人数为y,同时给一个长度为n的数组p,对应选区AB两党人数加起来必须>=pi,问能否合理分配每个党派的人数,使得结果满足字符串s,若能输出YES,否则输出NO

思路:

首先我们可以确定一个绝对不可能满足的条件:数组p全部人数加起来如果>x+y

然后我们在分类讨论其余情况

分类的标准是字符串s是否既有1又有0

那么为什么这么分类呢?

我们先明确一个地方:对于pi,如果si=0,那么A最少是pi/2+1,如果si=1,那么B最少是pi/2+1,也就是pi/2+1,pi-(pi/2+1)是保证胜利的最低保证

因为如果既有1又有0,那么无论A多的人数还是B多的人数,都能把这些人安插在他们赢的选区(消化掉多出的人数),而又因为我们一开始保证了x+y>=p全部和,所以只要AB两党人数>=其各自最低保证和即可。

而如果在只有0或者只有1的情况只下,AB人数过多之时,不好消化掉这些多出的人数

我们要单独讨论能不能消化这些多出的人

首先我们可以发现如果pi是偶数,那么两个最低保证之间相差2,例如若pi=4,那么pi/2+1=3,pi-(pi/2+1)=1,也就是说这些偶数时候天然多出来一个空隙可以存放多出人数,去除掉这些人,如果还有多的,假设去除后多的人为r

当si全是0时,此时如果r是偶数,那么AB平分即可,而如果r是奇数那么A就得比B多一个人,因为si=0,如果x>最低保证+消化多出的人,那么就符合

si全是1时同理

代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
void solve() {
    int n, x, y;
    cin >> n >> x >> y;
    string s;
    cin >> s;
    int c = 0;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        c += a[i];
    }
    if (x+y< c) {
        cout << "NO" << endl;
        return;
    }
    int e = count(s.begin(), s.end(), '0');
    int g = n - e;
    if (e && g) {
        int h = 0, i = 0;
        for (int j = 0; j < n; j++) {
            int k = a[j] / 2 + 1;
            if (s[j] == '0') h += k;
            else i += k;
        }
        if (x >= h && y >= i) cout << "YES" << endl;
        else cout << "NO" << endl;
        return;
    }
    if (g == 0) { 
        int m = 0, o = 0;
        for (int i = 0; i < n; i++) {
            m += a[i] / 2 + 1;
            if ((a[i] & 1) == 0) o++;
        }
        int r = x + y - c - o;
        int ss = 0;
        if (r > 0) ss = (r + 1) / 2;
        int tt = m + ss;//最低保证+消化多出的人
        if (x >= tt && x <= d) cout << "YES" << endl;
        else cout << "NO" << endl;
        return;
    }
    int m = 0, o = 0;
    for (int i = 0; i < n; i++) {
        m += a[i] / 2 + 1;
        if ((a[i] & 1) == 0) o++;
    }
    int r = x + y - c - o;
    int ss = 0;
    if (r > 0) ss = (r + 1) / 2;
    int tt = m + ss;//最低保证+消化多出的人
    if (y >= tt && y <= d) cout << "YES" << endl;
    else cout << "NO" << endl;        
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
相关推荐
草履虫建模1 天前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq1 天前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq1 天前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
爱吃rabbit的mq1 天前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
(❁´◡`❁)Jimmy(❁´◡`❁)1 天前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi1 天前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
不能隔夜的咖喱1 天前
牛客网刷题(2)
java·开发语言·算法
VT.馒头1 天前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
进击的小头1 天前
实战案例:51单片机低功耗场景下的简易滤波实现
c语言·单片机·算法·51单片机
咖丨喱1 天前
IP校验和算法解析与实现
网络·tcp/ip·算法