Codeforces Round 916 (Div. 3)(A~F)

题目地址Codeforces Round 916 (Div. 3)

标程给出了伪代码,完整代码模板在最后一题。

Problems A. Problemsolving Log

思路

给出一个字符串,字符串包含 A − Z A-Z AZ,表示 26 26 26个问题, A − Z A-Z AZ的难度分别为 1 − 26 1-26 126。字符串第 i i i个位置出现的问题表示当前在思考该问题。解决每个问题需要思考该问题的时间大于等于其难度,因此直接用一个map来记录即可,当该问题被解决后,将其赋值为 − I N F -INF INF

标程

void Solved() {
    int n; cin >> n;
    string s; cin >>s;
    int res = 0;
    map<char, int> mp;
    for(int i = 0; i < n; i ++ ) {
        mp[s[i]] ++;
        if(mp[s[i]] >= s[i] - 'A' + 1) {
            res ++;
            mp[s[i]] = -INF;
        }
    }
    cout << res << endl;
}

Problems B. Preparing for the Contest

思路

题目给定两个整数 n , k n,k n,k,分别表示有元素为 1 − n 1-n 1n的数列, k k k表示数列中有 k k k a i < a i + 1 a_i < a_{i+ 1} ai<ai+1的组合。要求输出符合题目要求的数组排列。

我们只需要顺序输出前 k k k个元素然后逆序输出剩余元素即可得到。

标程

void Solved() {
    int n, k; cin >> n >> k;
    
    for(int i = 1;  i <= k; i ++ ) {
        cout << i  << " ";
    }
    for(int i = n; i > k; i --  ) {
        cout << i << " ";
    }
    cout << endl;
}

Problems C. Quests

思路

题目给定 n , k n,k n,k,表示有编号为 1 − n 1-n 1n n n n个任务,然后Monocarp可以完成 k k k个任务,每个任务可重复完成。

每个任务有两个经验值,第一个经验值是第一次完成任务时能获得的经验值,第二个经验值是之后重复完成时每次能获得的经验值。

题目要求输出最大经验值。

我们考虑到完成第 i i i个任务的前提是完成前 i − 1 i-1 i1个任务。假设我们需要完成前 i ( i < k ) i(i<k) i(i<k)个任务,那么至少需要完成 i i i个任务,多余的任务我们可以选前 i i i个任务中第二个经验值最大的任务来做。

那么结果为: r e s = M A X ( ∑ j = 1 i a [ j ] + c [ i ] × ( k − i − 1 ) ) res = MAX(\sum_{j=1}^{i}{a[j]}+c[i] \times(k-i-1)) res=MAX(j=1ia[j]+c[i]×(ki1)),$0\le i \le MIN(n-1, k-1) $, i i i为枚举的前若干项, c [ i ] c[i] c[i]为前 i i i中第二经验值的最大值。

标程

#define int long long
void Solved() {
	int n, k; cin >> n >> k;
	vector<int> a(n), b(n), c(n);
 
	for(auto &i : a) cin >> i;
	for(auto &i : b) cin >> i;
 
	for(int i = 1; i < n; i ++ ) {
		a[i] += a[i - 1];
	}
	int mx = 0;
	for(int i = 0; i < n; i ++) {
		if(b[i] > mx) c[i] = b[i], mx = b[i];
		else c[i] = mx;
	}
	int res = 0;
	for(int i = min(n - 1, k - 1); i >= 0; i -- ) {
		res = max(res, a[i] + c[i] * (k - i - 1));
	}
	cout << res << endl;
}

Problems D. Three Activities

思路

给定三个长度为 n n n的数组,要求从每个数组中选择一个数,要求选择的三个整数下标互不相同且总和最大。

所选的数字必定为三个数组中前三大的数字,因此用sort排个序,然后枚举一下所有可能,输出最大值即可。

标程

#define int long long 
#define ALL(x) x.begin(), x.end()

bool cmp(PII n1, PII n2) {
    return n1.fi < n2.fi;
}
 
void Solved() {
    int n; cin >> n;
    vector<PII> a(n), b(n), c(n);
    vector<PII> x, y, z;
    int res = 0;
 
    for(int i = 0; i < n; i ++ ) {
        cin >> a[i].fi; a[i].se = i;
        
    }
    for(int i = 0; i < n; i ++ ) {
        cin >> b[i].fi; b[i].se = i;
    }
    for(int i = 0; i < n; i ++ ) {
        cin >> c[i].fi; c[i].se = i;
    }
    sort(ALL(a)); sort(ALL(b)); sort(ALL(c));
 
    for(int i = n - 3; i < n; i ++ ) {
        for(int j = n - 3; j < n; j ++ ) {
            if(a[i].se == b[j].se) continue;
            for(int k = n - 3; k < n; k ++ ) {
                if(a[i].se == c[k].se) continue;
                if(b[j].se == c[k].se) continue;
                res = max(res, a[i].fi + b[j].fi + c[k].fi);
            }
        }
    }
    
    cout << res << endl;
}

Problems E1&E2. Game with Marbles

思路

根据题目设置的游戏条件,每次一个人选择一个颜色的弹珠,然后将自己的该弹珠个数减一,并将对方的减为零,当有一方该颜色弹珠个数为零时不能选择改颜色。当所有颜色都不能选时游戏结束。Alice和Bob都希望游戏结束后自己的弹珠比对方的多。

容易发现,当前选择的最优解必然是选择两种玩家弹珠数之和最大的颜色。当选择两玩家弹珠数之和最大的颜色时,可令两玩家弹珠总和之差拉开最大。

按照最优方式,玩家选择的颜色顺序是根据两玩家该颜色总和降序来选,因此我们按照总和最大对颜色进行排序,然后进行遍历。

当为奇数步时,Alice选择,则 r e s + = a [ i ] . a − 1 res+=a[i].a-1 res+=a[i].a1,因为此时 a [ i ] . b = 0 a[i].b = 0 a[i].b=0,因此 a [ i ] . a − 1 a[i].a-1 a[i].a1可以表示为这次选择将会拉开的差距。偶数步同上。

标程

#define int long long 
#define ALL(x) x.begin(), x.end()

struct node {int a, b, c, x;};
 
bool cmp(node n1, node n2) {
    return n1.c > n2.c;
}

void Solved() {
    int n; cin >> n;
    vector<node> a(n);
    int res = 0;
 
    for(auto &i : a) cin >> i.a;
    for(auto &i : a) cin >> i.b;
    for(int i = 0; i < n; i ++ ) {
        a[i].c = a[i].a + a[i].b;
        a[i].x = i;
    }
    sort(ALL(a), cmp);
    
    for(int i = 0; i < n; i ++ ) {
        if((i + 1) & 1) {
            res += a[i].a - 1;

        } else {
            res -= a[i].b - 1;
        }
    }
    cout << res << endl;
}

Problems F. Programming Competition

思路

给出 n n n个节点,然后给出 2 − n 2-n 2n的父节点,要求找出组合 ( a , b ) (a,b) (a,b) a , b a,b a,b相互不为其父节点或父节点的父节点的个数。

标程

#include<bits/stdc++.h>

using namespace std;

#define IOS ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr);
#define LL long long 
#define ULL unsigned long long 
#define PII pair<int, int>
#define lowbit(x) (x & -x)
#define Mid ((l + r) >> 1)
#define ALL(x) x.begin(), x.end()
#define endl '\n'
#define fi first 
#define se second

const int INF = 0x7fffffff;
const int Mod = 1e9 + 7;
const int N = 2e5 + 10;	

vector<int> a[N];
int b[N], f[N];

void dfs(int u) {
	int id = 0;
	b[u] = f[u] = 1;

	for(auto v : a[u]) {
		dfs(v);
		b[u] += b[v];
		if(b[v] > b[id]) id = v;
	}
	f[u] = 1 + ((b[u] - 1) & 1);
	if(f[id] > b[u] - 1 - b[id]) f[u] = 1 + f[id] - (b[u] - 1 - b[id]);
}

void Solved() {
	int n; cin >> n;

	for(int i = 1; i <= n; i ++ ) a[i].clear(), b[i] = f[i] = 0;

	for(int i = 2; i <= n; i ++ ) {
		int x; cin >> x;
		a[x].push_back(i);
	}

	dfs(1);
	
	cout << (n - f[1]) / 2 << endl;
}

signed main(void) {
    IOS

	int ALL = 1; 
	cin >> ALL;
	while(ALL -- ) Solved();
	// cout << fixed;//强制以小数形式显示
	// cout << setprecision(n); //保留n位小数

    return 0;
}
  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值