湘大 XTU OJ 1291 Buying Gifts 题解(非常详细):枚举 维护最小值 排序

一、链接

1291 Buying Gifts

二、题目

题目描述

快到年末了,Boss Liu准备在年会上发些礼物,由于不想礼物的价格区别太大,Boss Liu希望最好的礼物与最差的礼物价格相差越小越好。 当然,如果存在相同的选择,Boss Liu希望花的钱越少越好
Boss Liu把这个买礼物的任务给你,你决定写个程序来帮助自己计算一下。

输入

第一行是一个整数K,表示样例的个数。
每个样例的第一行是一个整数n,m(1≤m≤n≤1000),分别表示可购买的礼物的个数和实际需要购买的个数
每个样例的第二行是n个整数xi,i=1,2,⋯,n(1≤xi≤100),表示n个礼物的价格

输出

每个样例输出两个整数,分别表示最小的价差以及总的花费,中间用一个空格隔开。

样例输入

2
5 3 
10 5 9 7 2 
5 1 
10 5 9 7 2

样例输出

3 26 
0 2

线索

第一个样例,购买10,9,7的礼物的差值最小为3,总花费是26。
第二个样例,因为只买一样所以差值都是0,最小花费是2。

三、题意

输入可供选择的商品,选择一定的商品,保证选择的商品可以使得价差最小,在价差相等的情况下,总金额越小越好,输出最小的价差和总的金额

四、代码

c++代码

#include
#include

using namespace std;

const int N=1000+10;

int gap,temp=110,ans,sum;

int q[N];

int main()
{
	int t;
	scanf("%d",&t);
	
	while(t--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		
		for(int i=0;i

c语言代码

#include

int q[1000+10],ans,gap,temp=110,sum;

int main()
{
	int t;
	scanf("%d",&t);
	
	while(t--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		
		for(int i=0;iq[j])
				{
					int k=q[i];
					q[i]=q[j];
					q[j]=k;
				}
			}
		}
		
		for(int i=0;i+b-1

五、总结

1.首先把输入的数字进行一个升序排序,c++直接调用库函数,c语言直接手写一个冒泡排序

算是常见的模板,排序相关可以参考这一篇:湘大 XTU OJ 1097 排序 题解:c++ 函数库的使用 快速排序 归并排序 冒泡排序

2.思路类似于滑动窗口,我们只需要看固定窗口内的几个元素(也就是我们要买的礼物个数) 

单调队列-求一定范围内的最大值和最小值

像是这一个题目的朴素做法 

3.根据样例简单模拟一下:有五个商品可供选择,我们只需要买3个礼物,刚开始是

10,5,9,7,2

4.排序之后是

2,5,7,9,10

5.每一次看三个元素

2,5,7,9,10

2,5,7,9,10

2,5,7,9,10

维护每一次黄色区域的最大值和最小值的差值,第一个是5,第二个是4,第三个是3,所以答案就是3,然后输出第三个黄色区域的和

6.题目要求在最大值与最小值差值最小的情况下,如果两组数据最小的差值相等,输出总钱数最小的那个答案,也就是输出黄色区域总和最小的答案,使用这一行代码即可实现

if(gap

也就是说不取等号,这样的话,就会自然取左边的黄色区域,因为已经按照升序排序,所以左边的黄色区域的总和更小 

7.有一个地方容易绕晕:从1开始数到n是n个数字,从0开始数到n-1是n个数字

8.最后不要忘记重置所有变量,因为每一个样例输入,答案都会发生改变

9.最大的价差不会超过99,所以把temp初始化为110,可以保证任何情况下,temp都至少被更新一次,任何一个价差都小于temp的初始值

六、精美图片

湘大 XTU OJ 1291 Buying Gifts 题解(非常详细):枚举 维护最小值 排序_第1张图片

 

你可能感兴趣的:(算法竞赛,湘大,XTU,OJ,算法,c++,数据结构)