C++贪心算法

排队打水

题目描述 有 n个人排队到 r个水龙头去打水,他们装满水桶的时间 t_1,t_2,...,t_n 为整数且各不相等,应如何安 排他们的打水顺序才能使他们花费的总时间最少? 每个人打水的时间 = 排队的时间 + 实际打水的时间,本题假设一个人打好水,排在他后面的人接着打 水的这个切换过程不消耗时间。 比如,有 2 个人 A和 B ,他们打水的时间分别是 3 和 2 ,只有 1个水龙头,这时,如果 A 先打水,B 后打水,那么 A 和 B 打水的时间分别为 3、3+2( B 排队 3 分钟)。因此,所有人打水的总时间就是 每个人的打水时间及每个人的排队时间的总和。 输入 第 1 行,两个整数 n(1≤n≤500)和r (≤r≤100)。 第 2 行,n个正整数 t_1,t_2,...,t_n (≤ti≤1000)表示每个人装满水桶的时间。 输出 1 行,一个正整数,表示他们花费的最少总时间

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
int a[110];
int n,r;
int sum = 0; 
int main()
{
	cin>>n>>r;
	for(int i = 0;i<n;i++)
	{
		cin>>a[i];
	}
	sort(a+0,a+n);
	for(int i = 0;i<n;i++)
	{
		if(i>=r)
		{
			a[i] = a[i-r] + a[i];
		}
		sum = sum + a[i];
	}
	cout<<sum;
	
	return 0;
} 

拦截导弹的系统数量求解

比如: 有8颗导弹,飞来的高度分别为 389 207 175 300 299 170 158 165 那么需要2个系统来拦截,他们能够拦截的导弹最优解分别是: 系统1:拦截 389 207 175 170 158 系统2:拦截 300 299 165 输入 两行,第一行表示飞来导弹的数量 n(n≤1000) 第二行表示n颗依次飞来的导弹高度; 输出 要拦截所有导弹最小配备的系统数k。 样例 输入复制 8 389 207 175 300 299 170 158 165 输出复制 2 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能 够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。 假设某天雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。 输入n个导弹依次飞来的高度(给出的高度数据是不大于30000的正整数),计算如果要拦截所有导弹最少要配备多少套 这种导弹拦截系统。

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
int a[1100];
int la = 0;
int n; 
int main()
{
	cin>>n;
	for(int i = 0;i<n;i++)
	{
		int tmp;
		cin>>tmp;
		bool f = false; 
		for(int j = 0;j<la;j++)
		{
			if(a[j]>=tmp)
			{
				a[j] = tmp;
				f = true;
				break;
			}
		}
		if(f == false)
		{
			a[la] == tmp;
			la++;
		}
	}
	cout<<la;
	return 0;
} 

最大子矩阵

描述 已知矩阵的大小定义为矩阵中所有元 素的和。给定一个矩阵,你的任务是 找到最大的非空(大小至少是1 * 1)子矩 阵。 比如,如下4 * 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15。 输入 输入是一个N * N的矩阵。输入的第一行给出N (0 < N

#include<iostream>
#include<algorithm>
using namespace std;
int a[110][110];
int b[110][110];
int n;
int main()
{
	cin>>n;
	for(int i = 1;i<=n;i++)
	{
		for(int j = 1;j<=n;j++)
		{
			cin>>a[i][j];
			b[i][j] = b[i][j-1] + [i][j];
		}
	}
	for(int i = 1;i<=n;i++)
	{
		for(int j = 1;j<=n;j++)
		{
			b[i][j] = b[i-1][j] + a[i][j];
			
		}
	}
	int ma = -1;
	for(int sx = 1;sx<=n;sx++)
	{
		for(int sy = 1;sy<=n;sy++)
		{
			for(int ex = sx;sx<=n;sx++)
			{
				for(int ey = sy;ey<=n;ey++)
				{
					int h = b[sx-1][sy-1] + b[ex][ey] - b[ex][sy-1] - b[sx-1][ey]
				}
			}
		}
	}
	cout<<ma;
	
	return 0;
} 

整数区间

【题目描述】 请编程完成以下任务: 1.读取闭区间的个数及它们的描述; 2.找到一个含元素个数最少的集合,使得对于每一个区间,都至少有 一个整数属于该集合,输出该集合的元素个数。 【输入】 首行包括区间的数目n,1≤n≤10000,接下来的n 行,每行包括两个整数a,b,被一空格隔开,0≤a≤b≤10000,它们是某 一个区间的开始值和结束值。 【输出】 第一行集合元素的个数,对于每一个区间都至少有一个整数属于该 集合,且集合所包含元素数目最少。

#include<iostream>
using namespace std;
void func(int scd,int ecd); 
int main()
{
	int n;
	cin>>n;
	func(1,n);
    return 0;	
} 
void func(int scd,int ecd)
{
	if(scd == ecd)
	{
		cout<<scd<<" ";
		return;
	}
	cout<<scd<<" ";
	func(scd+1,ecd);
}

均分纸牌

移动规则: 每次可以移动任意的张数,第1堆可以移向第2堆, 第2堆可以移向第1堆或第3堆,。。。。。。 第n 堆只可以移向第n -1堆。 例如,当n=4时: 堆号 1 2 3 4 张数 3 5 4 8 移动的方法有许多种, 其中的一种方案: ① 第2堆向第1堆移动2张,成为:5 3 4 8 ② 第4堆向第3堆移动3张,成为:5 3 7 5 ③ 第3堆向第2堆移动2张,成为:5 5 5 5 经过三次移动,每堆都成为5张。 输入 第一行一个整数n。 第二行n个整数,用空格分隔。 输出 一个整数(表示最少移动次数)。 样例 输入复制 4 3 5 4 8 输出复制 3 题目描述 有n堆纸牌(2≤n≤200),排成一行,编号分别为1,2,…n。 已知 每堆纸牌有一定的张数,且张数之和均为n的倍数。移动各堆中的 任意张纸牌,使每堆的数量达到相同,且移动次数最少。

#include<iostream>
using namespace std;
int main()
{
	int a[210];
	int n;
	cin>>n;
	int sum = 0;
	for(int i = 0;i<n;i++)
	{
		cin>>a[i];
		sum = sum + a[i];
	}
	int avg = sum/n;
	int cnt = 0;
	for(int i = 0;i<n;i++)
	{
		a[i] = avg;
		cnt++;
		a[i+1] = a[i+1] + (a[i]-avg);
	}
	cout<<cnt;
	
	return 0;
} 

过河的最短时间

题目描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助 手电筒的话,大家是无论如何也不敢过桥去的。 不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。 如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需 要的时间就是走得比较慢的那个人单独行动时所需的时间。 问题是,如何设计一个方案,让这N人尽快过桥,计算成绩这N个人的最短过 桥时间。 比如:有四个人甲乙丙丁,他们过河需要的时间分别为,甲:1 乙:2 丙:5 丁:10 第一种办法:最快的2个人先过桥,然后让跑的最快的人来回去接剩下的人: 先让甲乙过去(2分钟),甲回来(1分钟),甲丙过去(5分钟),甲回来 (1分钟),甲丁再过去(10分钟),总共需要19分钟就可以让四个人都过去。 第二种办法:让最慢的地2个人一起过桥,减少最慢的人在桥上的次数 先让甲乙过去(2分钟),甲回来(1分钟),丙丁过去(10分钟),乙回来 (2分钟),甲乙再过去(2分钟),总共需要17分钟可以让四个人都过去。 那么最慢的时间就是需要17分钟! 输入 每组测试数据的第一行是一个整数N(1共有N个人要过河 每组测试数据的第二行是N个整数Si,表示这N个人过河所 需要花时间。(0所有人过河的最短时间

#include<iostream>
using namespace std;
int main()
{
	int a[100];
	int n;
	cin>>n;
	for(int i = 0;i<n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	int t = a[2];
	int p1 = n-1;
	int p2 = n;
	while(true)
	{
		int t1 = a[i] + a[p1] + a[1] + a[p2];
		int t2 = a[1] + a[p2] + a[2] + a[2];
		t = min(t1,t2);
		if(p1 == 3 || p1 ==4) break;
	}
	if(p1 == 4)
	{
		t == t + a[1] + a[3];
	}
	cout<<t;
	return 0;
} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值