CF Round 119 C-E

C

题目:传送门

思路:简单题不多说

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long
ll num_st[4005];
ll max_num_st[4005];
ll ans_num[4005];
ll n, k, x, m, tt;
string s;
bool check_ganghao = false;
 
void clear(ll n) {
	for (ll i = 1;i <= 2 * n;i++) {
		num_st[i] = 0;
 
		ans_num[i] = 0;
	}
}
void out_ganghao(ll deep, ll deep_num) {
	ans_num[deep] = deep_num - 1;
	for (ll i = deep + 1;i <= tt;i++) {
		ans_num[i] = max_num_st[i] - 1;
	}
	ll j = 1;
	ll i = 0;
	while (i <= m - 1) {
		if (s[i] == 'a') {
			cout << s[i];
			i++;
			continue;
		}
		if (s[i] == '*') {
			while (s[i] == '*' && i <= m - 1)
				i++;
			for (ll q = 1;q <= ans_num[j];q++) cout << 'b';
			j++;
			if (i == m - 1 && s[i] != 'a') break;
			continue;
		}
	}
	cout << '\n';
	return;
}
ll find_mid(ll l, ll r, ll num, ll deep) {
	ll mid = (l + r) / 2;
	if (mid * num == x) {
		out_ganghao(deep, mid);
		check_ganghao = true;
		return 0;
	}
	if (mid * num > x && (mid - 1) * num < x) return mid;
	if (mid * num > x) return find_mid(l, mid, num, deep);
	if (mid * num < x) return find_mid(mid + 1, r, num, deep);
}
void find(ll deep, ll num) {
	if (max_num_st[deep] * num < x)	find(deep - 1, num * max_num_st[deep]);
	if (check_ganghao) return;
	if (max_num_st[deep] * num == x) {
		out_ganghao(deep, max_num_st[deep]);
		check_ganghao = true;
		return;
	}
	if (max_num_st[deep] * num > x) {
		ll l = 1, r = max_num_st[deep];
		ll mid = find_mid(l, r, num, deep);
		if (mid == 0) return;
		ans_num[deep] = mid - 1;
		x -= (num * (mid - 1));//重点关注 
		return;
	}
}
void work() {
	cin >> n >> k >> x;
	cin >> s;
	if (n == 1) {
		cout << "a\n";
		return;
	}
	clear(n);
	check_ganghao = false;
	m = s.size();
	ll j = 0;
	for (ll i = 0;i <= m - 1;i++) {
		if (s[i] == '*' && i == 0 || s[i] == '*' && s[i - 1] == 'a') {
			j++;
			num_st[j]++;
			continue;
		}
		if (s[i] == '*') num_st[j]++;
	}
	for (ll i = 1;i <= j;i++) max_num_st[i] = num_st[i] * k + 1;
	tt = j;
	if (tt == 0) {
		cout << s << '\n';
		return;
	}
 
	find(tt, 1);
	return;
}
int main() {
	ios::sync_with_stdio(false);
	ll t;
	cin >> t;
	while (t--) {
 
		work();
	}
	return 0;
}

D

题目:传送门

思路:因为1和2的数量最大值不是很多,多了的话可以用3代替,那么枚举1和2的数量然后二分3的数量,贪心+枚举即可

代码:

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int n;
int a[1000015];
void work(){
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	
	int res=inf; 
	for(int x1=0;x1<=1;x1++){
		for(int x2=0;x2<=2;x2++){
			int ans=0;
			for(int i=0;i<n;i++){
				int cnt=INF;
				for(int sx1=0;sx1<=x1;sx1++){
					for(int sx2=0;sx2<=x2;sx2++){
						int v=a[i]-sx1-sx2*2;
						if(v>=0&&v%3==0) cnt=min(cnt,v/3);
					}
				}
				ans=max(ans,cnt);
			}
			res=min(res,ans+x1+x2);
		}
	}
	cout<<res<<endl;
} 
int main(){
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	int T;
	cin>>T;
	while(T--){
		
	}
	return 0;
}

E

之前写过单独E的题解

传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值