2019年新生训练赛 第⑨场题解

感觉怎么说呢,现在写的代码很别扭,自己都有点看不太惯。算了,废话说那么多也没啥意思,还是速度写题解,写完回去学习。珍惜现在,好好做自己的事,少废话,

A:Mahmoud and Ehab and the MEX

题意:增加或减少数组的元素,使数组中没有的最大非负整数为x,最少操作数?

解法:找到比x小而且数组里没有的个数,把这些数加到数组里面,如果x在数组里面再把它拿掉,就可以得到邪恶数组

  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int n,x;
    	int a[111]={0};
    	cin>>n>>x;
    	for(int i=0;i<n;++i)	cin>>a[i];
    	sort(a,a+n);
    	int i=0;
    	while(a[i]<x&&i<n)	++i;//找到最后一个比x小的数的位置
    	int count=0;
    	if(a[i]==x)	count=x-i+1;//x-ix小的数的个数
    	else count=x-i;
    	cout<<count<<endl;
    	//system("pause");
    	return 0;
    }

B:If at first you don't succeed...

题意:n个学生,一个没通过考试的孩子数了数通过考试去两个餐馆庆祝的同学人数分别为a,b,有c个同学两个餐馆都去了,

这个孩子想知道他有没有数错,和他一样没通过考试的有几个同学

解法:没通过考试的人数为t=n-(a+b-c),且t>0(因为这个孩子自己没通过考试)。最后注意下a,b,c都小于n-1,a,b都大于c

  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int a,b,c,n;
    	cin>>a>>b>>c>>n;
    	int t=n-(a+b-c);
    	if(a>n-1||b>n-1||c>n-1||c>a||c>b||t<1)
    		cout<<-1<<endl;
    	else	cout<<t<<endl; 
    	return 0;
    }

C. Urbanization

题意:n 元素的数组,选出n2,n3个元素的子集,使两子集的平均和最大

解法:元素最少的子集优先选取最大的元素,另一个子集选取剩余元素中最大的元素,求两个子集的平均值加和输出

  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int n1,n2,n3;
    	cin>>n1>>n2>>n3;
    	double a[n1+11];
    	if(n2>n3)	swap(n2,n3);
    	for(int i=0;i<n1;++i){
    		cin>>a[i];
    	}
    	sort(a,a+n1);
    	double count1=0.,count2=0.;
    	for(int i=n1-1;i>=n1-n2;--i){
    		count1+=a[i];
    	}
    	for(int i=n1-1-(min(n2,n3));i>n1-1-(n2+n3);--i)
    		count2+=a[i];
    
    	printf("%0.8f",count1/n2+count2/n3);
    	return 0;

D. Proper Nutrition

题意:输入n,a,b,是否能找到整数x,y使x·a + y·b = n成立。能输出YES,x,y否则输出NO

解法:判断是否存在x,n-b*x能被a整除

  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	long long n,a,b;
    	cin>>n>>a>>b;
    	int i=0;
    	while(i*a<=n){
    		if((n-i*a)%b==0){
    			cout<<"YES"<<endl<<i<<' '<<(n-i*a)/b<<endl;
    			return 0;
    		}
    		++i;
    	}
    	cout<<"NO"<<endl;
    	return 0;
    }

E. Developing Skills

题意:k次操作,每次操作可使数组中某一元素加1,且a[i]<=100 , k次操作后最大\sum a[i]/10 ?

解法:统计个位数字出现的次数,并同时统计原数组中\sum a[i]/10,优先让个位数字最大的增加到10。若个位数字为0,让没加到100的元素增加。

  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	long long n,k,a[11]={0};
    	cin>>n>>k;
    	long long count=0;
    	for(long long  i=0;i<n;++i){
    		long long te;
    		cin>>te;
    		count+=te/10;
    		a[10-te%10]++;
    	}
    	int te=n*9-count+a[10];//n个元素最大有n*10个10
    	for(int i=1;i<10;++i){
    		if(k<=a[i]*i){
    			count+=k/i;
    			k=0;
    			break;
    		}
    		else{
    			count+=a[i];
    			k-=a[i]*i;
    	}
    	}
    	if(k/10>=te)	count+=te;
    	else count+=k/10;
    	cout<<count<<endl;
    	return 0;
    }

F:图论题,听说不太难,改天补吧,马上考试的有点慌先去复习

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值