算法编程题积累——腾讯笔试"有趣的数字“问题
Posted 甘乐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法编程题积累——腾讯笔试"有趣的数字“问题相关的知识,希望对你有一定的参考价值。
本题基本思路:先对原序列进行排序,再根据不同情况采用不同算法。
首先差最大的对数最好求:用最小的数的个数 × 最大的数的个数即可。
接着求差最小的对数:
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之后容器、变量的初始化、有重复关键字在序列末尾的情况、无重复关键字时求最小差对数比较符号的选择等。
以上是关于算法编程题积累——腾讯笔试"有趣的数字“问题的主要内容,如果未能解决你的问题,请参考以下文章