C++排队接水

最近由于省级比赛将近,更新频率从明天(7月1日)起改为每日一更(或两更),与常州市赛/江苏省赛有关内容也会减少。谢谢大家的支持!

原题链接:https://www.luogu.com.cn/problem/P1223排队接水 - 洛谷排队接水 - 洛谷https://www.luogu.com.cn/problem/P1223排队接水 - 洛谷


题目描述

有n个人在一个水龙头前排队接水,假如每个人接水的时间为T_iTi​请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小。

输入

第一行为一个整数n。

第二行n个整数,第i个整数Ti​表示第i个人的等待时间Ti。

输出

输出文件共两行,第一行为一种平均时间最短的排队顺序。

第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。

样例组

输入
10 
56 12 1 99 1000 234 33 55 99 812

输出
3 2 7 8 1 4 9 6 10 5
291.90

说明/提示

n≤1000,ti ≤10^6n≤1000,ti​≤106,不保证ti​不重复。

当ti重复时,按照输入顺序即可(sort 是可以的)。


解题思路

        根据题目提示(sort 是可以的),我们可以知道这是一道简单排序性贪心。简单排序性贪心的题目主程序就一句话:

sort(a+1,a+n+1);//a是目标数组

        所以这道题目的难点还是统计与计数部分。 

        这道题目也可以被定义为基于冒泡的贪心。基于冒泡的贪心就是在冒泡排序中途进行一系列操作,那主要就是冒泡排序的程序。基于冒泡的贪心主程序如下:

//源程序见https://blog.csdn.net/ceshyong/article/details/125460633?spm=1001.2014.3001.5502
void bubble_sort(int n,int &a[],int &b[])
{
    for(int i=1;i<=n;i++) b[i]=i;
	for(int i=1;i<=n;i++)
	{
		bool f=0;
		for(int j=1;j<n;j++)
		{
            if(a[j]>a[j+1])
            {
                swap(b[j],b[j+1]);
                swap(a[j],a[j+1]);
                f=1;
            }
        } 
		if(f==0)	return;
	} 
}

        而由于统计与计数方式不同,基于简单排序性贪心也有两种方法。

        第一种办法是双循环(类似快排sort)+三数组。这种方法比较麻烦,但也是最基础的一种方法。用这种办法写的程序如下:

void cx(int n,int &a[],int &b[],int &u)
{
    for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(a[i]==b[j])
		    {
		    	if(u[j]==0)
		    	{
		    	  u[j]=1;
		    	  cout<<j<<' ';
				}
			}
		}
	}	
}

第三种方法是借助STL库里的pair<>。用STL库写这样定义: 

vector<pair<int,int> >a;

输入的方法如下:

void dr(int n)
{
    int m;
	for(int i=1;i<=n;i++)
	{
		cin>>m;
		a.push_back(make_pair(m,i));
	}
}

然后直接sort(a.begin(),a.end())就行了。


代码

具体代码如下:

基于简单排序性贪心代码:

#include<bits/stdc++.h>
#define maxn 10002
using namespace std;
int a[maxn],b[maxn],n,res;
void bubble_sort()
{
    for(int i=1;i<=n;i++) b[i]=i;
	for(int i=1;i<=n;i++)
	{
		bool f=0;
		for(int j=1;j<n;j++)
		{
            if(a[j]>a[j+1])
            {
                swap(b[j],b[j+1]);
                swap(a[j],a[j+1]);
                f=1;
            }
        } 
		if(f==0)	return;
	} 
}
int main()
{
	double t=0;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	bubble_sort(); 
	for(int i=1;i<=n;i++)  cout<<b[i]<<' ',t+=a[i]*(n-i);
	cout<<endl<<fixed<<setprecision(2)<<t/n;
	return 0;
}

有图为证。 

 基于冒泡的贪心代码:

#include<bits/stdc++.h>
using namespace std;
int a[100001],u[100001],b[100001],n;
int main()
{
	double time=0;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
	  cin>>a[i];
	  b[i]=a[i];
    }
	sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(a[i]==b[j])
		    {
		    	if(u[j]==0)
		    	{
		    	  u[j]=1;
		    	  cout<<j<<' ';
				}
			}
		}
	}	
	for(int i=1;i<=n;i++)  time+=a[i]*(n-i);	
	cout<<endl<<fixed<<setprecision(2)<<1.0*time/n;
	return 0;
}

有图为证(梅开二度) :

 基于STL的代码:

#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int> >a;int n,m,res;double t=0;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>m;
		a.push_back(make_pair(m,i));
	}
	sort(a.begin(),a.end());
	for(int i=0;i<n;i++)	cout<<a[i].second<<' ';
	for(int i=1;i<n;i++)	res+=a[i-1].first,t+=res;
	cout<<endl<<fixed<<setprecision(2)<<t/n;
	return 0;
}

有图为证(三羊开泰):

 这道题目就这么多(花了我两个多小时,写死我了)。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值