Codeforces Round #574 (Div. 2)

本文解析了四道编程题目:饮品选择问题、体育黑帮问题、篮球训练问题及潜艇在里宾斯克海问题的简单版与复杂版。通过算法与数据结构展现了问题解决过程,涉及动态规划、方程求解等技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Drinks Choosing

签到题,就是对每一种饮料都可以拿好多次,在拿饮料总和有限的条件下,问最多能够满足多少人

    # include <bits/stdc++.h>
    using namespace std;
     
    const int MAXN=1e3+100;
    int a[MAXN];
    int main()
    {
    	int n,k;
    	int sum=0;
    	scanf("%d %d",&n,&k);
    	for(int i=1;i<=n;i++){
    		int aa;
    		scanf("%d",&aa);
    		a[aa]++;
    	}
    	
    	int b;
    	if(n%2==0) b=n/2;
    	else b=n/2+1;
    	
    	int c;
    	for(int i=1;i<=k;i++){
    		if(a[i]!=1){
    			c=a[i]/2;
    			if(c<=b){
    				sum+=c*2;
    				a[i]=a[i]/2*2;
    				b=b-c;
    			}else{
    				sum+=b*2;
    				a[i]=a[i]-b*2;
    				b=0;
    				break;
    			}	
    		}
    	}
    	
    	//cout<<"@@@"<<sum<<endl;
    	if(b){
    		for(int i=1;i<=k;i++){
    			if(b){
    				if(a[i]){
    					sum+=1;
    					a[i]=0;
    					b--;
    				}
    			}
    		}
    	}
    	
    	printf("%d",sum);
    	return 0;
    }

B. Sport Mafia

解一个方程即可,a*(a+1)/2-b=k,其中a+b==n;

    # include <bits/stdc++.h>
    using namespace std;
     
    typedef long long LL;
    int main()
    {
    	LL n,k;
    	scanf("%lld %lld",&n,&k);
    	
    	LL sum=0;
    	sum=(sqrt(9+8*(n+k))-3)/2;
    	
    	printf("%lld",n-sum);
    	return 0;
    }

C. Basketball Exercise

一维DP,总共有三种,对于当前的取h1[ i ],h2[ i ],不取列三个状态转移方程即可

    # include <bits/stdc++.h>
    using namespace std;
     
    const int MAXN=1e5+100;
    typedef long long LL;
    LL h1[MAXN];
    LL h2[MAXN];
    LL f[MAXN][3];
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&h1[i]); 
    	}
    	
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&h2[i]);
    	}
    	
    	for(int i=1;i<=n;i++){
    		f[i][0]=max(max(f[i-1][0],f[i-1][1]),f[i-1][2]);
    		f[i][1]=max(f[i-1][0],f[i-1][2])+h1[i];
    		f[i][2]=max(f[i-1][0],f[i-1][1])+h2[i];
    	}
    	
    	cout<<max(max(f[n][0],f[n][1]),f[n][2]);
    	return 0;
    }

D1. Submarine in the Rybinsk Sea (easy edition)

由于位数是一样的所以,(用12来举例好了),会变成1_2_,或者_1_2,每种有n个,相应计算即可

    # include <bits/stdc++.h>
    using namespace std;
     
    const int MAXN=1e5+100;
    typedef long long LL;
    LL a[MAXN];
    LL mod=998244353;
    int main()
    {
    	int n;
    	LL ans=0;
    	LL sum=0;
    	scanf("%d",&n);
    	
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&a[i]);
    		int b=11;
    		while(a[i]){
    			ans=(ans+(b*(a[i]%10))%mod)%mod;
    			b=((b%mod)*100)%mod;
    			a[i]=a[i]/10;
    			//cout<<b<<endl;
    			//cout<<"@@@"<<ans<<endl;
    		}
    		//cout<<ans<<endl;
    		sum=(sum%mod+ans)%mod;
    		ans=0;
    	}/*
    	for(int i=1;i<=n;i++){
    		LL t=11;
    		while(a[i]>0) ans=(1ll*a[i]%10*t)%mod,t=t*100%mod,a[i]=a[i]/10;
    		cout<<ans<<endl;
    	}*/
    	sum=(n*sum)%mod;
    	
    	printf("%lld",sum);
    	return 0;
    }

D2. Submarine in the Rybinsk Sea (hard edition)

和上面一个不一样的地方在于长度不一样了,那么可以这么想,对于每个数同一位的数字的地位是一样的,那么我们可以把这些加起来,当成一个去处理。对于每一位,位数相同的那么和上一题是一样的,但是位数多的哪一个,那么就是不在有位数的差,就是等于算了两次的那一位

    # include <bits/stdc++.h>
    using namespace std;
     
    typedef long long LL;
    LL mod=998244353;
    const int MAXN=1e5+100;
    char a[MAXN][30];
    LL wei[30];
    LL quick_pow(LL a,LL b)
    {
    	LL ret=1;
    	while(b)
    	{
    		if(b&1) ret=ret*a%mod;
    		a=a*a%mod;
    		b=b/2;
    	}
    	return ret%mod;
     } 
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	
    	for(int i=1;i<=n;i++){
    		scanf("%s",&a[i]);
    		for(int j=0;j<strlen(a[i]);j++){
    			wei[strlen(a[i])-j]+=a[i][j]-'0';
    		}
    	}
    	
    	LL sum=0;
    	for(int i=1;i<=n;i++){
    		int k=1;
    		LL t=11;
    		for(int j=0;j<strlen(a[i]);j++){
    			sum=(sum+(wei[k]*t%mod))%mod; 
    			t=((t%mod)*100%mod);
    			k++;
    		}
    		for(;k<20;k++){
    			sum=(sum+wei[k]*quick_pow(10,strlen(a[i])+k-1)%mod*2%mod)%mod;
    		}
    	}
    	
    	cout<<sum<<endl;
    	return 0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值