【算法题】有趣的数字

小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?

输入描述:

输入包含多组测试数据。

对于每组测试数据:

N - 本组测试数据有n个数

a1,a2…an - 需要计算的数据

保证:

1<=N<=100000,0<=ai<=INT_MAX.

输出描述:

对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。

输入例子:
6
45 12 45 32 5 6

输出例子:
1 2

妈蛋,被输入输出坑惨了,调的我要怀疑人生了。
题目要求对多组输入进行计算,每组输入两行,输出一行,直到终止
所以需要循环输入,且输出需要换行

  • 计算差最小个数
    - 如果数组中没有重复数字,说明最小差不为0,最小差肯定是数组中相邻两个数的差。因此,遍历一边数组,计算并统计最小差。
    - 如果数组中有重复数字,说明最小差是0:遍历一边map,数字个数不为1的,数字会产生最小差0,利用n*(n-1)/2计算即可
  • 计算差最大个数
    只有一种情况,最大值与最小值的两两组合,即最大值个数 * 最小值个数
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
using namespace std;

//#define debug

int main()
{

    int n;
    while(cin>>n)
    {
        map<int, int> map_;
        int tmp;
        for (auto i = 0; i < n; i++)
        {
            cin >> tmp;
            map_[tmp]++;
        }

        int maxnum = map_.rbegin()->second;
        int minnum = map_.begin()->second;
        int flag(0);
        for (auto iter = map_.begin(); iter != map_.end(); iter++)
        {
            if (iter->second > 1)
            {
                flag = 1;
            }
        }

        int min_count(0);
        int min_cord(99999);
        if (flag == 1)
        {
            for (auto iter = map_.begin(); iter != map_.end(); iter++)
            {
                int a = iter->second;
                if (a > 1)
                {
                    a = a*(a - 1) / 2;
                    min_count += a;
                }
            }
        }
        else
        {
            auto iter_pre = map_.begin();
            auto iter_cur = map_.begin();
            iter_cur++;
            for (; iter_cur != map_.end(); iter_cur++)//map的遍历是有序遍历
            {
                if ((iter_cur->first - iter_pre->first) < min_cord)
                {
                    min_cord = iter_cur->first - iter_pre->first;
                    min_count = 1;
                }
                else if ((iter_cur->first - iter_pre->first) == min_cord)
                {
                    min_count++;
                }
                iter_pre = iter_cur;
            }
        }

        cout << min_count;
        cout << " ";
        cout << maxnum*minnum<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值