RC-u4 攻略分队

时间限制
400 ms
内存限制
64 MB
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题解 :

  • 优先 和 唯一解
  • 两种选择,因此可以用“状态”表示来枚举所有情况
  • 注意函数中定义的数组值是随机的,必须初始化为0
  • 首先前提是都要有0位置,如果没有直接false;接下来保证了这个前提了,“优先选择每组有至少一个指挥和至少一个工兵的方案;“,“优先选择每组至少有一个指挥的方案“,这两个条件如果都不满足,说明只满足了“每组必须有至少一个 MT“这个前提条件,然后就是看人数和差异了
  • 如果第一次满足当前这个条件(且需要配合ok和okk来控制优先权和已经达到的优先权),直接更新okk和rs和rr就可以return true;如果不是第一次满足当前这个条件,就只需要更新okk
  • 两个vector之间比较字典序,可以直接用符号比较
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

int V[10];
bool special[10][5];
vector<int> notemp;
vector<int> a, b;
int q1[3], q2[3];
int rs;
bool rr;
int ok = -1;

bool check(vector<int> &x, vector<int> &y) {
    if (!x.size() || !y.size()) return false;
    memset(q1, 0, sizeof q1);
    memset(q2, 0, sizeof q2);
    int r1 = 0, r2 = 0;
    int okk = -1;
    for (auto i : x) {
        r1 += V[i];
        for (int j = 0; j < 3; ++ j) {
            if (special[i][j]) {
                q1[j] ++ ;
            }
        }
    }
    for (auto i : y) {
        r2 += V[i];
        for (int j = 0; j < 3; ++ j) {
            if (special[i][j]) {
                q2[j] ++ ;
            }
        }
    }
    if (!q1[0] || !q2[0]) return false;
    if (q1[1] && q1[2] && q2[1] && q2[2]) {
        if (ok < 2) {
            ok = 2;
            rr = (r1 - r2) > 0;
            rs = abs(r1 - r2);
            return true;
        }
        okk = 2;
    } else if (q1[1] && q2[1]) {
        if (ok < 1) {
            ok = 1;
            rr = (r1 - r2) > 0;
            rs = abs(r1 - r2);
            return true;
        }
        okk = 1;
    } else {
        if (ok < 0) {
            ok = 0;
            rr = (r1 - r2) > 0;
            rs = abs(r1 - r2);
            return true;
        }
        okk = 0;
    }
    if (okk == ok) {
        if (abs(r1 - r2) < rs) {
            rs = abs(r1 - r2);
            rr = (r1 - r2) > 0;
            return true;
        } else if (abs(r1 - r2) == rs) {
            bool rr2 = (r1 - r2) > 0;
            if (rr2 > rr) {
                rr = rr2;
                return true;
            } else if (rr2 == rr) {
                return (x < a);
            }
        }
    }
    return false;
}

int main() {
    for (int i = 0; i < 6; ++ i) {
        cin >> V[i];
        if (V[i]) notemp.push_back(i);
    }
    for (int i = 0; i < 6; ++ i) {
        string s;
        cin >> s;
        for (int j = 0; j < 3; ++ j) {
            special[i][j] = (s[j] - '0');
        }
    }
    int n = int(notemp.size());
    for (int i = 0; i < (1 << n); ++ i) {
        vector<int> x, y;
        for (int j = 0; j < n; ++ j) {
            if ((i >> j) & 1) x.push_back(notemp[j]);
            else y.push_back(notemp[j]);
        }
        if (check(x, y)) {
            a = x;
            b = y;
        }
    }
    if (!a.size() || !b.size()) {
        cout << "GG";
    } else {
        for (int i = 0; i < a.size(); ++ i) {
            cout << a[i] + 1;
            if (i != a.size() - 1) cout << ' ';
        }
        cout << endl;
        for (int i = 0; i < b.size(); ++ i) {
            cout << b[i] + 1;
            if (i != b.size() - 1) cout << ' ';
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值