2022 RoboCom 世界机器人开发者大赛-本科组(省赛)

发布时间 2023-07-12 15:06:16作者: PHarr

RC-u1 不要浪费金币

#include <bits/stdc++.h>

using namespace std;


int main() {
    ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);
    int n , m , res = 0 ;
    cin >> n >> m;
    for( int i = 1 , cnt = 0, x ; i <= n ; i ++ ){
        cin >> x;
        if( cnt + x > m ) cnt = 0 , res ++;
        cnt += x;
    }
    cout << res << "\n";
}

RC-u2 智能服药助手

用桶去维护一下每一种要上一次的服用时间即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

int32_t main() {
    ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);
    int n , m , res = 0 ;
    cin >> n >> m;
    vector<int> T(n+1);
    for( int i = 1 ; i <= n ; i ++ ) cin >> T[i];
    vector<int> last( n+1  , INT_MIN );
    for( int t , k ; m ; m -- ){
        cin >> t >> k;
        for( int x ; k ; k -- ){
            cin >> x;
            if( last[x] + T[x] <= t ) last[x] = t;
            else cout << "Don't take " << x << " at " << t << "!\n";
        }
    }
}

RC-u3 跑团机器人

首先我们根据加减号去划分表达式。

表达式有两种,两种的区分就要看表达式中有没有d,特判一下表达式第一个字符是d的情况。

对于掷骰子的情况,最小就是全 1 最大就是全 y ,对于每一个表达式都计算出他的取值范围就好了。

#include <bits/stdc++.h>

using namespace std;

#define int long long

map<int, int> cnt;

pair<int, int> calc(string s, int tag) {
    if (s.empty()) return make_pair(0, 0);
    int l = 0, r = 0, t = s.find('d');
    if (t < s.size()) {
        int a = 0, b = 0;
        if( t == 0 ) a = 1;
        else
            for (int i = 0; i < t; i++)
                a = a * 10 + s[i] - '0';
        for (int i = t + 1; i < s.size(); i++)
            b = b * 10 + s[i] - '0';
        l = a , r = a * b;
        cnt[b] += a;
    } else {
        for( auto i : s )
            l = l * 10 + i - '0';
        r = l;
    }
    if (tag == 0) swap(l, r), l = -l, r = -r;
    return make_pair(l, r);
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    string s, op = "";
    int tag = 1 , ansL = 0 , ansR = 0 ;
    cin >> s;
    s += '+';
    for (auto i: s) {
        if (i == '+' || i == '-') {
            auto [l, r] = calc(op, tag);
            ansL += l , ansR += r;
            op = "", tag = (i == '+');
        } else op += i;
    }
    
    for( const auto & [k,v] : cnt)
        cout << k << " " << v << "\n";
    cout << ansL << " " << ansR << "\n";
    return 0;
}

RC-u4 攻略分队

这道题数据量很小,直接用搜索枚举出所有的分队情况,然后题目定义的最优规则判断当前分队情况是否比已经记录的最优分队情况更优。

#include <bits/stdc++.h>

using namespace std;

#define int long long

typedef bitset<3> Node;

int resAV = 0, resAA = 0, resAB = 0, resAC = 0, resBV = 0, resBA = 0, resBB = 0, resBC = 0;
vector<int> v(7), resA, resB;
vector<Node> p(7);

#define update {resA = A, resB = B, resAA = AA, resBA = BA, resAB = AB, resBB = BB, resAC = AC, resBC = BC, resAV = AV, resBV = BV;return;}

void dfs(int i, vector<int> A, vector<int> B) {
    if (i > 6) {
        int AV = 0, AA = 0, AB = 0, AC = 0, BV = 0, BA = 0, BB = 0, BC = 0;
        for (auto j: A)
            AV += v[j], AA += p[j][2], AB += p[j][1], AC += p[j][0];
        for (auto j: B)
            BV += v[j], BA += p[j][2], BB += p[j][1], BC += p[j][0];

        // 2
        int r = (resAA > 0 && resBA > 0);
        int n = (AA > 0 && BA > 0);
        if (n == 0) return;
        else if (r == 0) update;

        //1
        r = (resAB > 0 && resAC > 0 && resBB > 0 && resBC > 0);
        n = (AB > 0 && AC > 0 && BB > 0 && BC > 0);
        if (r == 0 && n == 1) {
            update;
        } else if (r == 1 && n == 0)
            return;
        //2
        r = (resAC > 0 && resBC > 0);
        n = (AC > 0 && BC > 0);
        if (r == 0 && n == 1) {
            update;
        } else if (r == 1 && n == 0)
            return;

        //3
        r = abs(resAV - resBV);
        n = abs(AV - BV);
        if (n < r) {
            update;
        } else if (r < n) {
            return;
        }
        //4
        r = (resAV >= resBV);
        n = (AV >= BV);
        if (r == 0 && n == 1) {
            update;
        } else if (r == 1 && n == 0) {
            return;
        }
        //5
        if (A < resA) {
            update;
        } else if (resA < A) {
            return;
        }
        return;
    }
    if (v[i] == 0) {
        dfs(i + 1, A, B);
        return;
    }

    A.push_back(i);
    dfs(i + 1, A, B);
    A.pop_back();

    B.push_back(i);
    dfs(i + 1, A, B);
    B.pop_back();

    return;
}

int32_t main() {
    for (int i = 1; i <= 6; i++)
        cin >> v[i];
    for (int i = 1; i <= 6; i++)
        cin >> p[i];

    int totalA = 0;
    for (int i = 1; i <= 6; i++)
        totalA += p[i][2];
    if (totalA < 2) {
        cout << "GG\n";
        return 0;
    }


    dfs(1, vector<int>(), vector<int>());

    for (auto i: resA)
        cout << i << " \n"[i == resA.back()];
    for (auto i: resB)
        cout << i << " \n"[i == resB.back()];
    return 0;
}

RC-u5 树与二分图

这题感觉很简单吧,首先树一定是二分图。并且把节点按照深度的奇偶性就能很轻松的分开,若奇数深度点的数量为\(A\),偶数深度点的数量为\(B\),则边数最多是\(A\times B\),树本身已经链接\(n-1\)条边,所以答案就是\(A\times B - n + 1\)

#include <bits/stdc++.h>

using namespace std;

#define int long long

vector<vector<int>> e;
int A , B;

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

void dfs( int x , int p , int fa ){
    if(p) A ++;
    else B ++;
    for( auto y : e[x] )
        if( y != fa ) dfs( y , p^1 , x );
    return ;
}

int32_t main() {
    int n  = read();
    e = vector<vector<int>> (n+1);
    for( int t = n-1 , x , y ; t ; t -- )
        x = read() , y = read() , e[x].push_back(y) , e[y].push_back(x);

    dfs( 1 , 1 , -1 );

    cout << A * B - n + 1ll << "\n";
    return 0;
}