蓝桥杯-算法提高-双十一抢购-结构体+sort()排序+冒泡排序

蓝桥杯-算法提高-双十一抢购-结构体+sort()排序+冒泡排序

  • 问题描述
      一年一度的双十一又来了,某网购网站又开始了半价销售的活动。
      小G打算在今年的双十一里尽情地购物,以享受购买的极度快感,她已经列好了她想买的物品的列表。
      当然小G并不是出身富贵家庭,所以她网银里的钱只是一个有限的整数S(单位:元)。
      这次抢购她打算遵循这三个原则选择每一个物品:
      1.先买能“赚”最多的;
      2.在“赚”一样多的情况下,先买最便宜的(这样买的东西就可能更多了);
      3.在前两条里都判断不了购买顺序的话,先购买在列表里靠前的。

      (由于网站里还是有一部分商品并没有打五折,所以2的情况(“赚”的钱数为0)是完全可能发生的)
      现在,在双十一的这一天,你要帮小G编写一个程序,来看看她应该去买她列表里的哪些物品。(总价格不要超过S哦)
      要是帮她写好这个程序的话,或许你能在光棍节这一天里赢得她的芳心哦~
  • 输入格式
      输入共N+1行。
      第一行包含两个整数S和N,S表示小G的可用金额,N表示她看上的物品个数。
      接下来N行,对应每一个物品,每行有两个整数a和b,a是物品的原价(单位:元),b为0或1,若b为0,则此物品不半价,若b为1,则此物品半价销售。
  • 输出格式
      输出共一行,为小G要买的物品序号(从1开始),用空格隔开,注意按序号从小到大输出。
      若小G一件都买不了,则输出0.
  • 样例输入
    10 3
    5 0
    4 0
    10 1
  • 样例输出
    2 3
  • 样例输入
    10 3
    11 0
    21 1
    100 1
  • 样例输出
    0
  • 数据规模和约定
      0<S<=10000,0<N<=1000,每一个a和b满足0<a<=1000且b=0或1.
  • 解题思路:
    参考试题 算法提高 双十一抢购!!!
    1.先买能“赚”最多的;
    对于有半价活动的物品,按折后价从高到低排序:
bool cmp1(str x,str y){
	if(x.a!=y.a)
	   return x.a>y.a;
	if(x.num!=y.num) 
	   return x.num<y.num;
} 
sort(Y+1,Y+Ynum+1,cmp1);

2.在“赚”一样多的情况下,先买最便宜的(这样买的东西就可能更多了);
对于无半价活动的物品,按原价从低到高排序:

bool cmp2(str x,str y){
	if(x.a!=y.a)
	   return x.a<y.a;
	if(x.num!=y.num) 
	   return x.num<y.num;
} 
sort(N+1,N+Nnum+1,cmp2);

3.在前两条里都判断不了购买顺序的话,先购买在列表里靠前的。

  • AC代码:
#include<iostream>
#include<algorithm>
using namespace std;
double s;//s:可用金额
int n;//n:物品个数
struct str{
	double a;//物品的原价
	int num;//物品的序号
}; 
str Y[1002];//有半价的物品 
str N[1002];//无半价的物品
int Ynum=0;//有半价物品的个数 
int Nnum=0;//无半价物品的个数
bool cmp1(str x,str y){
	if(x.a!=y.a)
	   return x.a>y.a;
	if(x.num!=y.num) 
	   return x.num<y.num;
} 
bool cmp2(str x,str y){
	if(x.a!=y.a)
	   return x.a<y.a;
	if(x.num!=y.num) 
	   return x.num<y.num;
} 
int buy[1002];//储存要买的物品的序号 
int ans;//要买的物品个数 
int main(){
	cin>>s>>n;
	double x;//物品的原价
	int y;//是否有折扣 
	for(int i=1;i<=n;i++){
		cin>>x>>y;
		if(y==1){//此物品有半价 
		    Ynum++;
			Y[Ynum].num=i;
			Y[Ynum].a=x/2;	
		} 
		else{//无半价
		    Nnum++;
			N[Nnum].num=i;
			N[Nnum].a=x;
		}
	}	
	ans=0;//初始化要买的物品个数 
	sort(Y+1,Y+Ynum+1,cmp1);//有半价的物品按折后价格从大到小排序 
	for(int i=1;i<=Ynum;i++){
		if(s>=Y[i].a){
			buy[ans]=Y[i].num;
			s-=Y[i].a;
			ans++;
		}
	}
	sort(N+1,N+Nnum+1,cmp2);//无半价的物品按原价从小到大排序 
    for(int i=1;i<=Nnum;i++){
		if(s>=N[i].a){
			buy[ans]=N[i].num;
			s-=N[i].a;
			ans++;
		}
	}
	if(ans==0){
		cout<<0;
	} 
	else{//把要买的物品序号用冒泡排序从小到大排序 
		for(int i=0;i<ans;i++){
			for(int j=0;j<ans-i-1;j++){
				if(buy[j]>buy[j+1]){
					int t=buy[j];
					buy[j]=buy[j+1];
					buy[j+1]=t;
				}
			}
		}
		for(int i=0;i<ans;i++){
		    cout<<buy[i]<<" ";
	    }
	}
	return 0;
} 

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值