Codeforces Round 114 Div. 2(BCD)

Codeforces Round 114 Div. 2

B. Combinatorics Homework

给出字符a,b,c的数量,判断是否可以组成一个字符串,仅有m对相邻的字符相同。(需要用完所有字符)

解题思路:
求出整体的范围,直接判断m是否满足该范围即可

#include <bits/stdc++.h>
#define fo(a,b,c) for(int a=b;a<c;a++)
using namespace std;
typedef long long ll;
ll sum;
int main(){
    ios::sync_with_stdio(0);
    int n,a[3],m;
    cin>>n;
    while(n--){
        cin>>a[0]>>a[1]>>a[2]>>m;
        sum=a[0]+a[1]+a[2];
        sort(a,a+3);
        if(sum-3>=m&&sum-(a[0]+a[1])*2-1<=m) cout<<"yes"<<endl;
        else cout<<"no"<<endl;
    }

    return 0;
}

C. Slay the Dragon

解题思路:
排序后直接 lower_bound 找到大于等于 x 的英雄pos 让他去杀 dragon 即可。

#include <bits/stdc++.h>
#define fo(a,b,c) for(int a=b;a<c;a++)
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll sumA,a[N],x,y,sumD;
int main(){
    ios::sync_with_stdio(0);
    int n,m;
    cin>>n;
    fo(i,0,n) cin>>a[i],sumA+=a[i];
    sort(a,a+n);
    cin>>m;
    fo(i,0,m){
        cin>>x>>y;
        sumD=x+y;
        if(a[n-1]<=x){
            cout<<x-a[n-1]+max(y-sumA+a[n-1],0ll)<<endl;
            continue;
        }
        if(a[0]>=x){
            cout<<max(y-sumA+a[0],0ll)<<endl;
            continue;
        }
        int ar=lower_bound(a,a+n,x)-a,al=ar-1;
        if(a[al]==x){
            cout<<max(y-sumA+x,0ll)<<endl;
            continue;
        }
        cout<<min(x-a[al]+max(y-sumA+a[al],0ll),max(y-sumA+a[ar],0ll))<<endl;
    }

    return 0;
}

D. The Strongest Build BFS+暴力*

给定n个序列,要从每个序列选出一个数,价值为选出来的总和,然后有m个限制,代表m个序列不能用,求最大值

解题思路:
首先判断某种选择方案是否被 ban,可以直接使用 map 。我们将数组用 vector 存入,当做map的key值,之后判断是否存在这种 vector 即可。(好像不建议把数组当map的key值)
由于输入的 aij是递增的且数据量不大(n<11,m<1e5),考虑暴力搜索,我们可以从最外层选择 ci,即 max ⁡ { c i } , i ∈ [ 1 , n ] 开始往里bfs 搜索即可,每次各减一步,一旦找到没有被 ban 的即为最大值。

#include <bits/stdc++.h>
using namespace std;
#define int long long
using ll = long long;
const int maxn = 2e5 + 6, INF = 0x3f3f3f3f, base = 13331, mod1 = 998244353, mod2 = 1e9 + 7;
int n, m, s, t;
vector <int> a[10], ans, b[maxn];
map <vector <int> , int> mp;
int main()
{
	cin >> n;
	for (int i = 0; i < n; ++ i) {
		int c;
		cin>>c;
		ans.emplace_back(c - 1);
		for (int j = 0; j < c; ++ j) {
			int x; cin>>x;
			a[i].emplace_back(x);
		}
	}
	cin >> m;
	for (int i = 0; i < m; ++ i) {
		for (int j = 0; j < n; ++ j) {
			int x;cin>>x;
			x -- ;
			b[i].emplace_back(x);
		}
		mp[b[i]] = 1;
	}

	if(mp.find(ans) == mp.end()) {
		for (auto it : ans)
			cout << it + 1 << ' ';
		puts("");
		return ;
	}
	int res = 0;
	for (int i = 0; i < m; ++ i) {
		int sum = 0;
		for (int j = 0; j < n; ++ j)
			sum += a[j][b[i][j]];
		for (int j = 0; j < n; ++ j) {
			if(b[i][j] == 0) continue;
			sum -= a[j][b[i][j]];
			b[i][j] -- ;
			sum += a[j][b[i][j]];
			if(mp.find(b[i]) == mp.end())
				if(sum > res)
					ans = b[i], res = sum;
			sum -= a[j][b[i][j]];
			b[i][j] ++ ;
			sum += a[j][b[i][j]];
		}
	}
	for (auto it : ans)
		cout << it + 1 << ' ';
	puts("");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值