Codeforces Global Round 25

文章描述了四个编程问题,涉及C++代码实现,包括双触发器、战斗奶牛、购票策略和购买珠宝。主要展示了如何通过逻辑分析和优化算法解决这些问题,强调了条件判断和逐步添加限制的重要性。
摘要由CSDN通过智能技术生成

A. Dual Trigger

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int n;
string s;
void solve() {
	cin>>n;
	cin>>s;
	int cnt=0;
	for(int i=0;i<n;i++){
		if(s[i]=='1') cnt++;
	}
	if(cnt==2){
		for(int i=0;i<n-1;i++){
			if(s[i]=='1'&&s[i+1]=='1'){
				cout<<"NO"<<endl;
				return;
			}
		}
	}
	if(cnt%2) cout<<"NO"<<endl;
	else cout<<"YES"<<endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
    cin>>t;
	while(t--) {
		solve();
	}
	return 0;
}

B. Battle Cows

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=1e5+10;
int a[N];
int n,k;
void solve() {
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	int maxn=0;
	for(int i=1;i<=k-1;i++){
		maxn=max(maxn,a[i]);
	}
	//不换
	int ans1=0;
	if(a[k]<maxn) ans1=0;
	else{
		if(k!=1) ans1++;
		for(int i=k+1;i<=n;i++){
			if(a[k]>a[i]) ans1++;
			else break;
		}
	}
	//和第二个换
	int ans2=0;
	swap(a[k],a[2]);
	maxn=0;
	for(int i=1;i<=2-1;i++){
		maxn=max(maxn,a[i]);
	}
	if(a[2]<maxn) ans2=0;
	else{
		ans2++;
		for(int i=2+1;i<=n;i++){
			if(a[2]>a[i]) ans2++;
			else break;
		}
	}
	swap(a[2],a[k]);
	//和比它大的第一个换
	int ans3=0;
	int pos=-1;
	for(int i=1;i<=n;i++){
		if(a[i]>a[k]){
			pos=i;
			break;
		}
	}
	if(pos!=-1) {
		swap(a[k],a[pos]);
		maxn=0;
		for(int i=1;i<=pos-1;i++){
			maxn=max(maxn,a[i]);
		}
		if(a[pos]<maxn) ans3=0;
		else{
			if(pos!=1) ans3++;
			for(int i=pos+1;i<=n;i++){
				if(a[pos]>a[i]) ans3++;
				else break;
			}
		}
	}
	cout<<max({ans1,ans2,ans3})<<endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
    cin>>t;
	while(t--) {
		solve();
	}
	return 0;
}

C. Ticket Hoarding

参考Codeforces Global Round 25 A-F - 知乎 (zhihu.com)

如果有多个条件限制的话,那么一个一个考虑,先考虑限制简单的条件,然后一个一个往上加

首先,如果不考虑票价增长这一条件,那么肯定是买票价低的,而且尽可能买满m张票

然后加上票价增长这一条件,我们之后所选择的单价都会增加,比如说前面买了x张,那么后面买的单价增加x,发现实际上增加的票价和原先买票的价钱是独立的,只不过每次增加了当前票买的张数*前面买的票的总张数,发现式子中只有张数,并没有票价,所以和买的票的顺序无关,只和每次买的张数有关,所以优先买票价低的,然而我们肯定每次尽可能买的多,因为前面票价低,这是直观上的感觉

如果分析的时候可以定量的话,那么就定量分析:

现在就是看如何分配每次买的票的张数最优,对不同情况进行定量分析比较,看哪种更优

如果我们每次一张一张买的话,那么增量是1+2+…+k-1=k * (k-1)/2

如果我们第一次买x张的话,后面一张一张买的话,那么增量是x+(x+1)+(x+2)+…+(x+k-x-1)=x * (k-x)+1+2+…+k-x-1=x * (k-x)+(k-x)*(k-x-1)/2=(k-x) * (k+x-1)/2=k * (k-1)/2-x * (x-1)/2

比较一下,发现增量是减了x * (x-1)/2

所以优先买票价低的,并且每次尽可能买的多

trick:

1.如果有多个条件限制的话,那么一个一个考虑,先考虑限制简单的条件,然后一个一个往上加

2.如果分析的时候可以定量的话,那么就优先定量分析

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=3e5+10;
int a[N];
int n,m,k;
void solve() {
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+1+n);
	int cnt=0;
	int ans=0;
	for(int i=1;i<=n;i++){
		int count=min(m,k);
		ans+=a[i]*count;
		ans+=cnt*count;
		cnt+=count;
		k-=count;
		if(k==0) break;
	}
	cout<<ans<<endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
    cin>>t;
	while(t--) {
		solve();
	}
	return 0;
}

D. Buying Jewels

首先如果n小于k,肯定无解

如果n等于k,那么只要一个商店,价格定为1

构造题,我们可以这样构造, 两个商店,第二个商店价格定为1,让它刚好剩余价钱为k-1,那么就可以买到k-1个

那么就让第一个商店花的钱为n-(k-1)=n-k+1,但是必须保证n/(n-k+1)==1,这样,总共刚好可以买到k个

此时,n%(n-k+1)=k-1==>n-k+1>k-1==>k<(n+2)/2

否则,如果不满足以上条件,那么k大概接近或超过n的一半了,那么肯定价格不能定为3及以上了,只能定为1或者2了,进行验证即可

参考Codeforces Global Round 25 A - F - 知乎 (zhihu.com)

实际上,最后一种情况无解,具体证明见Codeforces Global Round 25(A-E)-CSDN博客

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int n,k;
bool check(vector<int>a){
	int total=0;
	int sum=n;
	for(auto x:a){
		total+=sum/x;
		sum%=x;
	}
	if(total==k){
		cout<<"YES"<<endl;
		cout<<a.size()<<endl;
		for(auto x:a) cout<<x<<' ';
		cout<<endl;
		return true;
	}
	return false;
}
void solve() {
	cin>>n>>k;
	if(n<k){
		cout<<"NO"<<endl;
		return;
	}
	if(n==k){
		cout<<"YES"<<endl;
		cout<<1<<endl;
		cout<<1<<endl;
		return;
	}
	int next=k-1;
	if(n/(n-next)==1){
		cout<<"YES"<<endl;
		cout<<2<<endl;
		cout<<n-k+1<<' '<<1<<endl;
		return;
	}
	if(!check({2,1})&&!check({2})&&!check({1})) cout<<"NO"<<endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
    cin>>t;
	while(t--) {
		solve();
	}
	return 0;
}
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值