强化阶段 Day 12 算法笔记 4.4 贪心

目录

1.月饼

2.组个最小数

3.区间贪心

4.To Fill or Not to Fill

5.Magic Coupon

6.Sort with Swap(0, i)运行超时


1.月饼

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

struct moon{
	double num;
	double whole_price;
	double single_price;
}martix[1005];

bool cmp(moon a,moon b){
	return a.single_price>b.single_price;
}

int main(){
	int n;
	double d;
	scanf("%d%lf",&n,&d);
	for(int i=0;i<n;i++){
		scanf("%lf",&martix[i].num);
	}
	for(int i=0;i<n;i++){
		scanf("%lf",&martix[i].whole_price);
		martix[i].single_price=martix[i].whole_price/martix[i].num;
	}
	sort(martix,martix+n,cmp);
	double ans=0.0;
	for(int i=0;i<n;i++){
		if(d<=martix[i].num){
			ans+=martix[i].single_price*d;
			break;
		}else{
			d-=martix[i].num;
			ans+=martix[i].whole_price;
		}
	}
	printf("%.2f",ans);
	
}

2.组个最小数

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

int main(){
	
	int martix[10];
	int loc;
	for(int i=0;i<10;i++){
		scanf("%d",&martix[i]);
	}
	for(int i=1;i<10;i++){
		if(martix[i]!=0){
			martix[i]--;
			printf("%d",i);
			break;
		}
	}
	for(int i=0;i<10;i++){
		if(martix[i]!=0){
			for(int j=0;j<martix[i];j++){
				printf("%d",i);
			}
		}
	}
	return 0;
}

3.区间贪心

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=110;
struct interval{
	int left,right;
}martix[maxn];

bool cmp(interval a,interval b){
	if(a.left!=b.left) return a.left>b.left;
	else return a.right<b.right;
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d %d",&martix[i].left,&martix[i].right);
	}
	sort(martix,martix+n,cmp);
	int ans=1,left_last=martix[0].left;
	for(int i=1;i<n;i++){
		if(martix[i].right<=left_last){
			ans++;
			left_last=martix[i].left;
		}
	}
	printf("%d",ans);
	
	return 0;
}

4.To Fill or Not to Fill

整体的思路搭起来了,但是具体的实现好像有问题

我这个还是比较冗杂,晴神的做法思路更加清晰

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

struct sta{
	double distance;
	double unit_price;
}martix[505];

bool cmp(sta a,sta b){
	return a.distance<b.distance;
}

int main(){
	//油箱容量,终点距离,单位油能跑的距离 
	double tank_cap,des_dis,unit_gas_dis;
	//加油站数目 
	int gas_num;
	scanf("%lf%lf%lf%d",&tank_cap,&des_dis,&unit_gas_dis,&gas_num);
	for(int i=0;i<gas_num;i++){
		scanf("%lf %lf",&martix[i].unit_price,&martix[i].distance);
	}
	sort(martix,martix+gas_num,cmp);
	//ans即最后花费的价格,tank_now是目前油箱的油量,whole_run是加满油的状态能跑的距离 
	double ans=0.0,tank_now=0,dis_now=0,whole_run=unit_gas_dis*tank_cap;
	//当前位置 
	int pos=0;
	//不断循环 
	while(1){
		//目前到达的加油站的油价 
		double min_price=martix[pos].unit_price;
		//如果没有能到达的加油站比当前加油站价格还低,那就选其中最低的那个 
		double relative_min=10000000;
		int relative_pos;
		//到达该加油站时还能跑的距离 
		double run_now=tank_now*unit_gas_dis;
		//下一个该去的加油站的位置 
		int next_pos=-1;
		//记录范围内是否还有加油站 
		bool flag=true;
		//在能够到达的范围里,找到最便宜的
		for(int i=pos+1;martix[pos].distance+whole_run>=martix[i].distance;i++){
			flag=false;
			if(martix[i].unit_price<min_price){
				next_pos=i;
				min_price=martix[i].unit_price;
			}
			if(martix[i].unit_price<relative_min){
				relative_min=martix[i].unit_price;
				relative_pos=i;
			}
		}
		//如果有比我更便宜的加油站,那么flag==false并且next_pos=-1; 
		//如果范围内还有可以到达的加油站但是没有比我更便宜的,那么flag等于false,next_pos=-1;
		//如果范围内没有加油站了,那么flag==true
		
		//有比我更便宜的加油站
		if(next_pos!=-1){
			//如果我能直接到达这个加油站
			if(run_now>=martix[next_pos].distance-martix[pos].distance){
				tank_now-=(martix[next_pos].distance-martix[pos].distance)/unit_gas_dis;
				pos=next_pos;
				continue;
			//如果无法直接到达 
			}else{
				//交钱,加油,开车耗油,到达 
				double need_gas=(martix[next_pos].distance-martix[pos].distance)/unit_gas_dis-tank_now;
				ans+=need_gas*martix[pos].unit_price;
				tank_now=0;
				pos=next_pos;
				continue;
			}
		}
		
		
		//有加油站,但是都比我贵 
		if(!flag&&next_pos==-1){
			//如果可以到达终点
			if(martix[pos].distance+whole_run>=des_dis){
				//现在的油足够跑到终点 
				if(run_now>=des_dis+martix[pos].distance){
					printf("%.2f",ans);
				//现在的油不够,但是我可以在这里加最后一次油,跑到终点 
				}else{
					ans+=((des_dis-martix[pos].distance)/unit_gas_dis)*min_price;
					printf("%.2f",ans);
				}
				break;
			//无法到达终点,那么就把油箱充满,到能去的范围里最便宜的那个加油站去 
			}else{
				//交钱,加油,开车到目的地消耗油,到达目的地 
				ans+=(tank_cap-tank_now)*min_price;
				tank_now=tank_cap;
				tank_now-=(martix[relative_pos].distance-martix[pos].distance)/unit_gas_dis;
				pos=relative_pos;
				continue;
			}
		}
		
		//范围内没有加油站了 
		if(flag){
			//如果可以到达终点 
			if(martix[pos].distance+whole_run>=des_dis){
				//如果我现在的油足够跑到终点 
				if(run_now>=des_dis+martix[pos].distance){
					printf("%.2f",ans);
				//现在的油不够,但是我可以在这里加最后一次油,跑到终点 
				}else{
					ans+=((des_dis-martix[pos].distance)/unit_gas_dis)*min_price;
					printf("%.2f",ans);
				}
			//如果我现在油箱加满都无法到达终点 
			}else{
				printf("The maximum travel distance = %.2f",martix[pos].distance+whole_run);
			}
			break;
		}
	}

	
	return 0;
}

5.Magic Coupon

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

int main(){
	
	int n,m,martix1[100005],martix2[100005];
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&martix1[i]);
	}
	sort(martix1,martix1+n);
	scanf("%d",&m);
	for(int i=0;i<n;i++){
		scanf("%d",&martix2[i]);
	}
	sort(martix2,martix2+m);
	
	int ans=0;
	for(int i=0;i<n&&i<m;i++){
		if(martix1[i]*martix2[i]>0&&martix1[i]<0){
			ans+=martix1[i]*martix2[i];
		}else break;
	}
	int i,j;
	for(i=n-1,j=m-1;i>=0&&j>=0;i--,j--){
		if(martix1[i]*martix2[j]>0&&martix1[i]>0){
			ans+=martix1[i]*martix2[j];
		}else{
			break;
		}
	}
	printf("%d",ans);
	
	
	return 0;
}

6.Sort with Swap(0, i)运行超时

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

int main(){
	
	int martix[100005];
	int n;
	scanf("%d",&n);
	int num=n;
	int value,pos;
	for(int i=0;i<n;i++){
		scanf("%d",&value);
		martix[value]=i;
		if(value==i&&value!=0){
			num--;
		}
		if(value==0){
			pos=i;
		}
	}
	int swap_pos,ans=0;
	//pos是当前0所在的下标,swap_pos是当前这个下标代表的数字在的位置 
	while(num>0){
		//如果0在就在0坐标处,那么随机找一个还没有恢复位置的数字和零交换 
		bool flag=false;
		if(pos==0){
			int i;
			for(i=1;i<n;i++){
				if(martix[i]!=i){
					flag=true;
					ans++;
					pos=martix[i];
					martix[i]=0;
					martix[0]=pos;
					break;
				}
			}
			if(i==n){
				break;
			}
		}
		//交换0和0现在所在的坐标的数字的位置
		swap_pos=martix[pos];
		martix[pos]=pos;
		martix[0]=swap_pos;
		pos=swap_pos;
		ans++;
		num--;
	}
	printf("%d",ans);
	

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值