算法设计与分析——最大间隙问题

求解思路说明

本题输入的实数序列中存在最大值和最小值(设为left和right),在数轴上分别作为本题输入的所有实数的右边界和左边界,作为一个区间。
设输入的实数个数为n,则该区间被这些实数分为n-1段。若将该区间平分为n-1段,则每段长度为
len=(right-left)/(n-1)
。根据鸽笼原理可知,相邻两个实数之间的最大差值(距离)
l≥len
。因此该相邻的两个实数在等分出的n-1段区间中一定位于两个不同的区间或都为区间端点,且其中较小数和较大数分别为各自所在等分区间所输入的实数中的最大值和最小值。因此,统计相邻等分区间之间较大区间中的最小实数值和较小区间中的较大实数值的差值,该最大差值即为这n个实数在数轴上相邻2个数之间的最大差值。

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef long long ll;
#define MAX 0x7fffffff

ll n;
double maxInterval=-MAX;

double findMax(double *a,ll n)
{
    double m=-MAX;
    for(ll i=0;i<n;++i)
    {
        if(a[i]>m)
        {
            m=a[i];
        }
    }
    return m;
}// 找到最大值

double findMin(double *a,ll n)
{
    double m=MAX;
    for(ll i=0;i<n;++i)
    {
        if(a[i]<m)
        {
            m=a[i];
        }
    }
    return m;
}// 找到最小值



int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);

    scanf("%lld",&n);
    double *a=(double *)malloc(n*sizeof(double));// 存放输入的实数
    for(ll i=0;i<n;++i)
    {
        scanf("%lf",&a[i]);
    }

    double left=findMin(a,n);
    double right=findMax(a,n);// 最大最小左右边界

    double *high=(double *)malloc((n-1)*sizeof(double));
    double *low=(double *)malloc((n-1)*sizeof(double));// 存放每个等分区间的最大最小数

    for(ll i=0;i<n-1;++i)
    {
        high[i]=left;
        low[i]=right;
    }


    for(ll i=0;i<n;++i)
    {
        ll num=(ll)((n-1)*((a[i]-left)/(right-left)));
        if(num>=n-1)
        {
            num-=1;
        }
        if(a[i]>high[num])
        {
            high[num]=a[i];
        }
        if(a[i]<low[num])
        {
            low[num]=a[i];
        }
    }// 扫描所有实数,更新每个等分区间中的最大最小值

    if(n==2)
    {
        printf("%lf\n",high[0]-low[0]);
        return 0;
    }

    for(ll i=0;i<n-2;++i)
    {
        if(i>0&&high[i]==left)
        {
            continue;
        }
        ll j;
        for(j=i+1;j<n-2&&low[j]==right;++j){}

        if(low[j]-high[i]>maxInterval)
        {
            maxInterval=low[j]-high[i];
        }
    }//计算并统计最大间隙
    printf("%lf\n",maxInterval);
    return 0;
}

算法运行截屏

输入数据文件input.txt:
在这里插入图片描述

算法运行过程中截图:
在这里插入图片描述

输出数据文件output.txt:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

long_red

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值