Codeforces Round 996 (Div. 2)

在这里插入图片描述

Codeforces Round 996 (Div. 2)

A. Two Frogs

题意:

从1到n一共n个坐标点,a和b分别在不同的点上, 每回合都必须向左或者向右移动一个坐标,二者不能重叠,由a先移动,一方不能移动则另一方获胜,a能否获胜。

思路:

显然,二者的间距为偶数时a总能获胜。

AC code:

void solve() {   
    int n, a, b;
    cin >> n >> a >> b;

    int d = abs(a - b);

    if (d % 2) {
        cout << "NO" << endl; 
    } else {
        cout << "YES" << endl; 
    }
} 

B. Crafting

题意:

有n种材料,每种材料现有 a i a_i ai单位,制作物品需要每种材料至少 b i b_i bi单位,每1单位材料可以花费其他(n-1)种材料各1单位进行兑换,是否可以成功制作物品。

思路:

模拟,若当前材料不够,记录需要其他材料提供 b [ i ] − a [ i ] b[i] - a[i] b[i]a[i]单位,需要额外提供的单位总和记录为 n o w now now,对于统计后的每一个单位,若在提供其他单位兑换材料后仍制作物品,即 ( a [ i ] − n o w < b [ i ] ) (a[i] - now < b[i]) (a[i]now<b[i])时,当前材料可以满足条件。

其中 n o w now now会额外减去为当前 a i a_i ai 提供的单位,需要在记录时额外添加 2 ∗ ( b [ i ] − a [ i ] ) 2 * (b[i] - a[i]) 2(b[i]a[i])

AC code:

void solve() {   
    int n; cin >> n;
    vector<int> a(n), b(n);
    int cnt = 1e9;
    for (int i = 0; i < n; i ++) cin >> a[i];
    int now = 0;
    for (int i = 0; i < n; i ++) {
        cin >> b[i];
        if (a[i] < b[i]) {
            now += b[i] - a[i];
            a[i] += 2 * (b[i] - a[i]);
        }
    }
    for (int i = 0; i < n; i ++) {
        if (a[i] - now < b[i]) {
            cout << "NO" << endl;
            return;
        }
    }
    cout << "YES" << endl;
} 

C. The Trail

题意:

有一篇n*m的山区,每个单元格为不同的高度,现在该区域被修改,有一条由(n+m-1)个单元格组成的由坐标(1,1)到坐标(n, m)的路径,移动方式只有向下和向右两种,移动路径会被标记高度为0,现在给出路径,还原原山区矩阵。

对于原山区矩阵,每一条横纵单元格的和均相等。

思路:

每一条横纵单元格的和均为0,然后进行模拟;

首先记录每一条横纵单元格的当前和,根据移动位置修改当前位置的数据;

若为纵向移动,则修改移动前行总和为0,若为横向移动,则修改移动前纵向总和为0;

AC code:

void solve() {   
    int n, m;
    cin >> n >> m;
    string s;
    cin >> s;

    vector<vector<int>> mat(n + 1, vector<int>(m + 1, 0));

    vector<int> row(n + 1, 0), col(m + 1, 0);

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> mat[i][j];
            row[i] += mat[i][j];
            col[j] += mat[i][j];
        }
    }
    int x = 1, y = 1;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] != 'D') {
            mat[x][y] = -col[y];
            row[x] -= col[y];
            col[y] = 0;
            y ++;
        } else { 
            mat[x][y] = -row[x];
            col[y] -= row[x];
            row[x] = 0;
            x ++;
        }
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (i == n && j == m) mat[i][j] = -col[m];
            cout << mat[i][j] << " ";
        }
        cout << endl;
    }
} 

D. Scarecrow

题意:

一只乌鸦当前在数轴0点位置,数轴上有n个点有稻草人,稻草人每秒可以向左或右移动一个单位;

乌鸦与坐标小于它的稻草人直接必须距离至少k个单位距离,否则就会瞬间传送(传送不耗时);

传送条件为,若当前稻草人单位x < 乌鸦单位y,且 y - x < k,则乌鸦瞬间传送到 y + k的位置;

现在乌鸦需要到达第m单位,需要的最短时间为多少。

注意,稻草人可能花费0.5s移动0.5个单位时,乌鸦就会触发条件瞬间移动!

思路:

模拟,初始时乌鸦在0点,最左边的稻草人至少需要花费a[0]单位时间到达0处,使得乌鸦瞬移到k点;

记录乌鸦当前位置now以及花费时间time;

若当前位置a[i] + time的稻草人依然小于等于当前乌鸦位置now,则直接瞬移到 a[i] + time + k点处;

若当前稻草人可以通过time的时间到达乌鸦当前位置,则乌鸦瞬移到now + k处

否则,需要额外的时间来触发乌鸦的移动,此时乌鸦左右均有稻草人,左侧稻草人距离乌鸦一定为k,乌鸦需要移动到超过右侧稻草人,则需要的时间为 (a[i] - time - now) / 2,因为两边的稻草人是相对移动的,当乌鸦触碰到右侧稻草人的瞬间可以移动到其+k的位置,此时乌鸦的位置为 now + (a[i] - time - now) / 2 + k;

直到乌鸦移动到终点,注意,输出答案是需要将浮点数转换为整数。

AC code:

void solve() {   
    int n, k, aim; cin >> n >> k >> aim;
    vector<int> a(n); 
    for (int i = 0; i < n; i ++) cin >> a[i];
    double time = a[0], now = k;
    for (int i = 1; i < n; i ++) {
        if (now >= aim) break;
        if (a[i] + time <= now) {
            now = a[i] + time + k;
        } else {
            if (abs(a[i] - now) <= time) {
                now += k;
            } else {
                double tmp = a[i] - time - now;
                tmp /= 2;
                time += tmp;
                now = now + tmp + k;
            }
        }
        
    }
    if (now < aim) {
        time += aim - now;
    }
    cout << (int)(time * 2) << endl;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值