10月OI练习讲解

  • gold
int main(){//累加、求最值
	int n,m,i,j,s,a,ans=0,no;
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++){
		s=0;
		for(j=0;j<m;j++){
			scanf("%d",&a);
			if(a%8==0)s+=a;
		}
		if(s>ans){
			ans=s;
			no=i+1;
		}
	}
	printf("%d",no);
	return 0;
}
  • poker
int main(){//穷举,求最值,累加
	int n,m,i,j,a[15],ans=0,no;
	string s;
	for(i=1;i<=13;i++){
		scanf("%d",a+i);
		if(a[i]>ans)ans=a[i];
	}		
	scanf("%d %d",&n,&m);
	ans*=m;
	cin>>s;
	n=s.size();
	for(i=0;i<n;i++){
		if(s[i]=='A')no=1;
		if(s[i]=='J')no=11;
		if(s[i]=='Q')no=12;
		if(s[i]=='K')no=13;
		if(s[i]>='2'&&s[i]<='9')no=s[i]-'0';
		if(s[i]=='1'){
			no=10;
			i++;
		}
		ans+=a[no];
	}
	printf("%d",ans);
	return 0;
}
  • rubbish
#define N 50005
using namespace std;
int r[N],p[N];
int main(){//贪心,队列。将垃圾和垃圾袋从小到大排序,然后一一对应着放就可以了
	int n,m,i,j,ans=0;		
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++)scanf("%d",r+i);
	for(i=0;i<m;i++)scanf("%d",p+i);
	sort(r,r+n);//排序
	sort(p,p+m);
	if(n>m){//垃圾多于垃圾袋则不能装完,本句可省略
		printf("-1");
		return 0;
	}
	i=j=0;//从第一堆垃圾和第一个垃圾袋开始
	while(i<n&&j<m){//挨个装,看是剩下垃圾还是垃圾袋
		if(r[i]<=p[j]){//如果能够装下就装
			ans+=p[j];
			i++;
			j++;
		}
		else j++;//不能装下就换一个大一点儿的垃圾袋
	}
	if(i>=n)printf("%d",ans);//i>=n说明垃圾都装下了
	else printf("-1");
	return 0;
}
  • toy
int k[20005],a[20005];//贪心枚举,可以处理50%的数据
int main(){
	int n,m,s,i,j,f;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		cin>>k[i];
	for(i=1;i<=n;i++)
		cin>>a[i];	
	for(i=20000;i>=0;i--){//枚举玩具数量,第一个满足条件的就是答案,因为本题最大值超过10亿,所以这种方法只能得部分分
		s=m;
		for(j=1;j<=n;j++)
		  if(a[j]*i>k[j]){//i个玩具需要的材料和库存材料相比较,看能否满足要求
		  	s=s-a[j]*i+k[j]; //不满足就用万能材料来补充
		  	if(s<0)//万能材料为负数了说明不能组装i个玩具
		  		break;
		  }
		if(s>=0){//枚举的第一个满足条件的就是答案
			cout<<i;
			return 0;
		}
	}	
	return 0;
}
#define N 100005 //二分的时间复杂度为Nlogn=100000*31,不会超时
using namespace std;
int x[N],y[N];
int main(){
	long long n,m,i,j,s,mid,low=0,high=2000000000;//玩具个数和材料的乘积可能会超过int范围	
	scanf("%lld %lld",&n,&m);
	for(i=1;i<=n;i++)scanf("%lld",x+i);
	for(i=1;i<=n;i++)scanf("%lld",y+i);
	do{
		mid=(low+high+1)/2;//二分取玩具可能个数,为保证每一种情况不会漏掉,需要+1
		s=m;//万能材料初始化给s
		for(j=1;j<=n;j++)
			if(mid*y[j]>x[j]){//每种材料所需数量与库存数量相比较
				s=s+x[j]-mid*y[j];//库存不足就用万能材料
				if(s<0)	break;//万能材料也不够说明玩具个数多了,需要减少玩具个数
			}	
		if(s<0)high=mid-1;//需要减少玩具个数,所以high=mid-1
		else low=mid;	//此处low的值不能为mid+1,玩具可能为mid个
	} while(low<high);
	printf("%lld",low);
	return 0;
}
/*
3 30
5 5 5
5 5 5
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值