• 链家网-后台开发工程师笔试题-第三题


    序言(废话)

    今天做链家网的笔试题, 选择题考的好杂好杂啊, php, java, C++ 几乎是等比重的考察,完全没有侧重,完全没有侧重。 幸亏都是基本语法, 大部分只要用心猜(反正编程语言都差不多了,毕竟咱是学C++的, 什么邪恶的写法没见过~~~~)。

    然后是笔试题, 其实笔试题三道都挺简单的, 只不过第三道题会卡时间。

    题目描述

    小恪要给学校里的人分组, 每个人的编号是连续的正整数(从1开始)。 然后根据某些同学的编号,查询它在哪个组里。

    输入描述

    第一行输入正整数 n, 代表总共有几数, 然后下一行输入 n 个正整数,表示每一个组有几个成员。
    第三行输入正整数m, 代表有 m 次的询问。 然后下一行有 m 个正整数, 表示询问编号为 Mi的成员,在哪一组?

    5
    2 7 3 4 9
    3
    1 25 11
    

    题目输出

    1
    5
    3
    

    数据范围

    1<= N <= 10^5, 1<= 每个组的成员数量 <= 10^6, 1<= M <= 10^5.

    解题代码

    方法一: 直接做

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #include <algorithm>
    #include <stdexcept>
    using namespace std;
    
    const int maxn = 100000 + 5; 
    long long arr[maxn]; 
    long long brr[maxn]; 
    
    int main()
    {
    	int n; 
    	cin >> n; 
    	arr[0] = 0; 
    	for(int i = 1; i <= n; i++)
    		cin >> arr[i]; 
    	for(int i = 2; i <= n; i++)
    		arr[i] = arr[i] + arr[i-1]; 
    	
    	int m; 
    	cin >> m; 
    	for(int i = 1; i <= m; i++)
    		cin >> brr[i]; 
    	for(int i = 1; i <= m; i++)
    	{
    		for(int j = 1; j <= n; j++)
    		{
    			if(arr[j] >= brr[i])
    			{
    				cout << j << endl; 
    				break; 
    			}
    		}
    	}		
    	
    	return 0; 
    }
    

    在规定的时间内,通过了 82%样例。 也就是说稍微有些超时~~~

    方法二: 用二分查找代替顺序查找

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxn = 100000 + 5; 
    long long arr[maxn]; 
    long long brr[maxn]; 
    
    int bSearch(long long arr[], int left, int right, long long val)
    {
    	while(left < right)
    	{
    		int mid = left + (right - left)/2;
    		if(arr[mid] < val)
    			left = mid+1; 
    		else if(arr[mid] > val)
    			right = mid; 
    		else
    			return mid; 
    	} 
    	
    	return left; 
    }
    
    int main()
    {
    	int n; 
    	cin >> n; 
    	arr[0] = 0; 
    	for(int i = 1; i <= n; i++)
    		cin >> arr[i]; 
    	for(int i = 2; i <= n; i++)
    		arr[i] = arr[i] + arr[i-1]; 
    	
    	int m; 
    	cin >> m; 
    	for(int i = 1; i <= m; i++)
    		cin >> brr[i]; 
    	for(int i = 1; i <= m; i++)
    	{
    		cout << bSearch(arr, 1, n+1, brr[i]) << endl; 
    	}		
    	
    	return 0; 
    }
    

    然而结果仍然是 82%, 好坑啊, 数据好没区分度啊!!!, 本来以为这种程度的优化绝壁就能过了, 于是就没打算写下面的第三种方法,结果。。。。悲剧了!!!!

    方法三: 空间换时间, 排序+hash

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 100000 + 5; 
    long long arr[maxn]; 
    long long brr[maxn]; 
    long long crr[maxn]; 
    
    int main()
    {
    	int n; 
    	cin >> n; 
    	arr[0] = 0; 
    	for(int i = 1; i <= n; i++)
    		cin >> arr[i]; 
    	for(int i = 2; i <= n; i++)
    		arr[i] = arr[i] + arr[i-1]; 
    	
    	int m; 
    	cin >> m; 
    	for(int i = 1; i <= m; i++)
    	{
    		cin >> brr[i]; 
    		crr[i] = brr[i]; 
    	}
    		
    	unordered_map<long long, long long> mm; 
    	sort(crr+1, crr+m+1);
    	int pos = 1;  
    	int i = 1; 
    	while(i <= n)
    	{
    		if(pos > m)
    			break; 
    			
    		while(arr[i] < crr[pos])
    			i++; 
    		mm[crr[pos]] = i; 
    		pos++; 	
    	}		
    	
    	for(int i = 1; i <= m; i++)
    		cout << mm[brr[i]] << endl; 
    		
    	return 0; 
    }
    
    

    毫无疑问, 这个提交绝不会超时,因为时间复杂度是O(NlogN)啊, 并且没有常数因子, 线段树也只能是这样的复杂度了吖。 但是, 但是, 链家网用的笔试OJ好差啊, 提交一个题目要十分钟 ~ ~ 。


    听说由于这个原因, 最后延时半小时 ~ ~ ~, 可是我已经提前交卷了, ~ ~ ~, 感觉好坑啊。 (当然主要还是怪自己没有再等等 ~ ~ ~)。 写篇博客,总结一下教训,不喜勿喷~~。



  • 相关阅读:
    Openresty+redis实现灰度发布
    Nginx keepalived
    Nginx反向代理、负载均衡、动静分离、缓存、压缩、防盗链、跨域访问
    MYCAT扩容
    MYCAT全局序列
    MYCAT分库分表
    MySQL主从复制
    [redis] linux下集群篇(4) docker部署
    [nginx] CORS配置多域名
    [mysql] 归档工具pt-archiver,binlog格式由mixed变成row
  • 原文地址:https://www.cnblogs.com/acm1314/p/7398052.html
Copyright © 2020-2023  润新知