Good Bye 2023 A - C 题解

首先祝大家元旦快乐呀!!!祝大家2024年一帆风顺!

A. 2023

题意:一共给你n个数字和一个k,想让你看看能否加k个数字,使全部数字乘积等于2023。
题解:暴力枚举即可,详情看代码。

代码:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 1e6 + 7 ;
inline int read(){
	int x = 0 , f = 1;
	char c = getchar() ;
	while(c > '9' || c < '0'){
		if(c == '-')
			f = -1 ;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		x = x * 10 + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
int t , n , m , k , a[maxn] , b[maxn] ;
vector < int > q ;
void solve(){
	n = read() ; 
	k = read() ;
	q.clear() ;
	int sum = 1 ;
	map < int , int > mp ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
		if(2023 % a[i] == 0){
			sum = sum * a[i] ;
			q.push_back(a[i]) ;
			mp[a[i]] ++ ;
		}
	}
	sort(q.begin() , q.end() , greater<>()) ;
	if(sum > 2023 || (int)q.size() != n){
		printf("NO\n") ;
		return ;
	}
	if(mp[119] > 1 || mp[17] > 2 || mp[7] > 1 || mp[2023] > 1 || mp[289] > 1){
		cout << "NO\n" ;
		return ;
	}
	int res = 2023 / sum ;
	if(k == 3){
		printf("YES\n") ;
		cout << 1 << " " << 1 << " " << res << endl ;
		return ;
	}
	if(k == 2){
		printf("YES\n") ;
		cout << 1 << " " << res << endl ;
		return ;
	}
	if(k == 1){
		printf("YES\n") ;
		cout << res << endl ;
		return ;
	}
	if(k == 4){
		printf("YES\n") ;
		cout  << 1 << " " << 1 << " " << 1 << " " << res << endl ;
		return ;
	}
	if(k == 5){
		printf("YES\n") ;
		cout << 1 << " " << 1 << " " << 1 << " " << 1 << " "<< res << endl ;
		return ;
	}
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

B. Two Divisors

题意:给你两个数字a和b。$1 < a < b < x$ ,看看能否找到一个x,使a和b是x($1 < x < 1e9$)的两个最大因子。
题解:首先可以看出,如果b是a的倍数,那么答案就是$b * (b / a)$ ,这很好理解,因为a是b的因子,所以$b * (b / a)$的最大两个因子一定是a和b。如果不是倍数,那么直接输出$n * m / (gcd( n , m))$ 。

代码:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 1e6 + 7 ;
inline ll read(){
	ll x = 0 , f = 1;
	char c = getchar() ;
	while(c > '9' || c < '0'){
		if(c == '-')
			f = -1 ;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		x = x * 10 + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
ll t , n , m , k , a[maxn] , b[maxn] ;
char s[maxn] ;
void solve(){
	n = read() ;
	m = read() ;
	if(m % n == 0){
		cout << m * (m / n) << endl ;
		return ;
	}
	ll res = n * m / __gcd(n , m) ;
	if(res != n && res != m){
		cout << res << endl ;
		return ;
	}
	cout << (n * m / __gcd(n , m)) * min(n , m) << endl ;
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

C. Training Before the Olympiad

题意:有两个玩家Masha和Olya,Masha先行,一共给你n个数字,每次操作可以合并$x_i$$x_j$,将他们合并成一个数字$(x_i + x_j) / 2 * 2$,输出最后合并剩下的一个答案,除以是下取整。Masha想让最后留下来的数字最大,Olya想让最后留下来的数字最小,每个人都用最优的方法来进行,问长度为$k = 1 , 2 , 3 , 4 , 5 .... n$ 的a数组,最后留下的数字最大是多少。
题解:因为是下取整,很容易想到会不会损失1的问题,所以看奇偶性,如果两个偶数或者两个奇数,那么不会有损失,$(x_i + x_j) / 2 * 2$的值就是$x_i + x_j$ 。 如果是一个奇数一个偶数那么答案相加下取整再乘2就是$x_i + x_j - 1$。所以问题就在于奇数的个数。分析到这里,做法也很明确了。Masha会优先合并两个奇数,Olya会优先让一个奇数和一个偶数搭配,这样答案就减少1。枚举奇数个数会发现,$ji = 1 , 3 , 4 , 6..$个奇数会减少,所以,如果(ji %3 == 1),那么答案会减少$(ji + 3 - 1) / 3$,如果(ji % 3 == 0),那么答案会减少$(ji / 3)$。整体复杂度$O(n)$

备注:一开始傻了没想到(ji % 3 == 1)会多减一,Wa了两发,寄!

代码:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e6 + 7 ;
inline ll read(){
	ll x = 0 , f = 1;
	char c = getchar() ;
	while(c > '9' || c < '0'){
		if(c == '-')
			f = -1 ;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		x = x * 10 + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
ll t , n , m , k , a[maxn] , b[maxn] ;
ll sum[maxn] ;
void solve(){
	n = read() ; 
	for(int i = 1 ; i <= n ; i ++){                
		a[i] = read() ;
	}
	sum[0] = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		sum[i] = sum[i - 1] + a[i] ;                                       
	}
	ll ji = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		if(a[i] % 2 == 1){
			ji ++ ;
		}
		if(i == 1){
			cout << a[i] << " " ;
			continue ;
		}
		if(ji % 3 == 1){
			cout << sum[i] - (ll)((ji + 3 - 1) / 3) << " " ;
			continue ;
		}
		if(ji == 0){
			cout << sum[i] << " " ;
			continue ;
		}
		if(ji == 1){
			cout << sum[i] - 1ll << " " ;
			continue ;
		}
		if(ji == 2){
			cout << sum[i] << " " ;
			continue ;
		}
		if(ji == 3){
			cout << sum[i] - 1ll << " " ;
			continue ;
		}
		if(ji == 4){
			cout << sum[i] - 2ll << " " ;                                      
			continue ;
		}
		if(ji >= 5){
			cout << sum[i] - (ll)(ji / 3ll) << " " ;
			continue ;
		}
	}
	cout << endl ;
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

喜欢作者的可以点点赞,点个宝贵的关注哦~

有问题可以私信作者,提出你的宝贵建议~

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
解题思路如下: 对于2023年国赛C题,我们可以按照以下步骤来解决问题: 1. 第一问: 首先,需要根据题目所给的数据和条件进行合理的建模。可以使用MILP模型来求解问题二,并根据销售空间及最小陈列量进行相应的限制。在求解阶段,可以设计0编码机制来适应销售空间限制,并通过修复机制保持染色体的合法性。另外,可以利用问题二中构建的动态调整模型进行调价决策。 2. 第二问: 对于问题二,需要分析各种类蔬菜的销售总量与成本加成定价之间的关系。可以建立集成拟合模型来拟合每种蔬菜单品的销量与成本利润率之间的关系。然后,根据成本利润率来确定销量,并给出每种蔬菜品类未来一周的日补货总量和定价策略。可以构建以最大化商超收益为目标的混合整数线性规划模型,并使用遗传算法对模型进行求解。 3. 第三问: 针对问题三,需要分析蔬菜各品类及单品销售量的分布规律及相互关系。可以从三个角度进行剖析: a) 各种类蔬菜的销售量分布和蔬菜种类与销售量之间的关系;b) 各种类蔬菜的销售量的月份分布和各种类蔬菜销售量与月份之间的相关关系;c) 各种类蔬菜的销售时间分布和销售时间与退货量之间的相关关系。可以利用箱线图和折线图来描述销量的分布特征,使用Kolmogorov-Smirnov分布检验来验证分布的一致性,并进行相关性分析来计算相关系数。 以上是解决2023年国赛C题的一些思路和方法。希望对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小许愿瓶

我的成长我做主

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值