zoukankan      html  css  js  c++  java
  • 算法编程题积累(4)——腾讯笔试"有趣的数字“问题

    本题基本思路:先对原序列进行排序,再根据不同情况采用不同算法。

    首先差最大的对数最好求:用最小的数的个数 × 最大的数的个数即可。

    接着求差最小的对数:

    1.当序列中无重复关键字时:可知最小差必然产生在相邻元素中,遍历一遍用map保存最小差的对数即可。

    2.当序列中有重复关键字时:首先确定最小差为0,故而对相同序列的个数依次用排列组合的知识求对数即可。

    AC代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 vector<int> ivec;
     5 int n, item, mindis, imin, imax, iequ;
     6 map<int, int> imap;
     7 bool flag;
     8  
     9  
    10 int main()
    11 {
    12     while(cin >> n)
    13     {
    14         ivec.clear();//每次读取n之后都要清空ivec
    15         for(int i = 0; i < n; ++i)
    16         {
    17            cin >> item;
    18            ivec.push_back(item);
    19         }
    20         stable_sort(ivec.begin(), ivec.end());
    21         mindis = INT_MAX;
    22         int len = ivec.size();
    23         imin = imax = 0;
    24         iequ = 1;
    25         flag = false;
    26         imap.clear();
    27         for(int i = 0; i < len-1; ++i)
    28         {
    29             if(ivec[i] > ivec[0] && ivec[i-1] == ivec[0])
    30                 imin = i;
    31             if(ivec[i] < ivec[len-1] && ivec[i+1] == ivec[len-1])
    32                 imax = len-1-i;
    33             if(ivec[i] == ivec[i+1])
    34                 flag = true;
    35         }
    36         if(flag == true)
    37         {
    38             mindis = 0;
    39             for(int i = 0; i < len-1; ++i)
    40             {
    41                 if(ivec[i+1] == ivec[i])
    42                 {
    43                     iequ++;
    44                 }
    45                 else {
    46                     if(iequ > 1)
    47                     {
    48                         imap[mindis] += iequ*(iequ-1)/2;
    49                         iequ = 1;
    50                     }
    51                 }
    52             }
    53             if(iequ > 1) //考虑相同关键字序列在末尾
    54                 imap[mindis] += iequ*(iequ-1)/2;
    55         } else {
    56             for(int i = 0; i < len-1; ++i)
    57             {
    58                 if(abs(ivec[i+1]-ivec[i]) <= mindis)//注意是<=
    59                 {
    60                     mindis = abs(ivec[i+1]-ivec[i]);
    61                     imap[mindis]++;
    62                 }
    63             }
    64         }
    65         cout << imap[mindis] << " " << imin*imax << endl;
    66     }
    67  
    68     return 0;
    69 }
     1 import java.util.*;
     2 
     3 public class Main {
     4     public static void main(String[] args) {
     5         Scanner sc = new Scanner(System.in);
     6         while(sc.hasNext()) {
     7             int n = sc.nextInt();
     8             int [] a = new int[n];
     9             for (int i = 0; i < n; ++i) {
    10                 a[i] = sc.nextInt();
    11             }
    12             Arrays.sort(a);
    13             boolean flag = false;
    14             int imin = 0, imax = 0;
    15             for (int i = 0; i < n-1; ++i) {
    16                 if(a[i] == a[i+1])
    17                     flag = true;
    18                 if(a[i] == a[0] && a[i+1] != a[0])
    19                     imin = i+1;
    20                 if(a[i] != a[n-1] && a[i+1] == a[n-1])
    21                     imax = n - 1 - i;
    22             }
    23             
    24             int mindis = 1000000000;                                                                        ;
    25             Map<Integer, Integer> map = new TreeMap<>();
    26             
    27             if(flag) {
    28                 mindis = 0;
    29                 int iequ = 1;
    30                 for (int i = 0; i < n-1; ++i) {
    31                     if(a[i] == a[i+1]) {
    32                         iequ++;
    33                     } else {
    34                         if (map.containsKey(mindis)) 
    35                             map.put(mindis, map.get(mindis)+iequ*(iequ-1)/2);
    36                         else
    37                             map.put(mindis, iequ*(iequ-1)/2);
    38                         iequ = 1;
    39                     }
    40                 }
    41                 if (iequ > 1) {
    42                     if (map.containsKey(mindis)) 
    43                             map.put(mindis, map.get(mindis)+iequ*(iequ-1)/2);
    44                         else
    45                             map.put(mindis, iequ*(iequ-1)/2);
    46                         iequ = 1;
    47                 }
    48             } else {
    49                 for (int i = 0; i < n-1; ++i) {
    50                     if (Math.abs(a[i+1]-a[i]) <= mindis) {
    51                         mindis = Math.abs(a[i+1]-a[i]);
    52                         if (map.containsKey(mindis))
    53                             map.put(mindis, map.get(mindis)+1);
    54                         else
    55                             map.put(mindis, 1);
    56                     }
    57                 }
    58             }
    59           System.out.println(map.get(mindis) + " " + imin*imax); 
    60         }
    61         sc.close();
    62     }    
    63 }

    这题AC关键是注意细节:每次读取n之后容器、变量的初始化、有重复关键字在序列末尾的情况、无重复关键字时求最小差对数比较符号的选择等。

  • 相关阅读:
    【AGC010 C】Cleaning
    【未知来源】火神的鱼
    【2017 北京集训 String 改编版】子串
    【未知来源】记忆
    【2017 江苏集训】子串
    【未知来源】循环移位
    【未知来源】K-th String
    【hdu 6067】Big Integer
    【CERC 2014 E】2048
    【hdu 6155】Subsequence Count
  • 原文地址:https://www.cnblogs.com/socrates-lzstu/p/6721927.html
Copyright © 2011-2022 走看看