阿里 笔试 机考 7.22

第一题90%

给一个n<=10,按字典序输出1...n,相邻数字绝对值不为1,的排列。

输入:
4
输出:
2 4 1 3
3 1 4 2

递归。n=10的情况卡python语言,没意思。只能90%。(c++貌似能递归100%)。
或许python换个写法也能100%。python这门语言其实挺恶心,一种操作有多种写法,时间复杂度还相差很悬殊

import sys
def f(vst, cur, lv):
    if lv == 0:
        print(' '.join(map(str, cur)))
    for i in range(1, len(vst)):
        if vst[i] or (len(cur) and i in [cur[-1]-1, cur[-1]+1]):
            continue
        vst[i] = 1
        f(vst, cur+[i], lv-1)
        vst[i] = 0
while True:
    iline = sys.stdin.readline()
    if iline == "":
        break
    n = int(iline)
    f([0]*(n+1), [], n) 

第二题100%

第一行两个整数n,m。m<=n<=400000。第二行是长度为n的数组a,a_i<=n。
计算a有多少个区间(子数组)满足:存在某个数字v,使得v在数组区间出现次数大于等于m。

输入:
5 2
1 2 1 2 5
输出:
5
解释:区间[1,3][1,4][1,5][2,4][2,5],要么1出现2次以上,要么2出现超过2次以上。

线性扫描。计算以i结尾的满足条件的区间数cnt[i]

根据题意有一个结论:对于以i结尾的区间,若j使得a[j...i]满足条件,则对j'<ja[j'...i]都满足条件。所以只要找到满足条件最大的j记作ptcnt[i]就等于pt+1了(不是pt)。

这样问题就转化成循环维护pt值。方法是,对已扫描的每个值v,记录其出现过的位置列表pos。扫描到a[i]时,查看到目前为止倒数第m-1次出现a[i]的位置pre_m(如果存在),且pre_m大于pt,则更新ptpre_m

O(N)时间,O(N)空间

import sys
def f(a, m):
    pt = -1
    ans = 0
    pos = [[] for i in range(len(a)+111)]
    for i in range(len(a)):
        v = a[i]
        pos[v].append(i)
        if len(pos[v]) >= m:
            pre_m = pos[v][-m]
            pt = max(pt, pre_m)
        ans += pt+1
    return ans
while True:
    iline = sys.stdin.readline()
    if iline == "":
        break
    n, m = list(map(int, iline.strip().split()))
    a = list(map(int, sys.stdin.readline().strip().split()))
    print(f(a, m))
#笔试题目#
全部评论
突然想问第 1 题打表可以么, n=10结果还是能用程序枚举出来的
1
送花
回复 分享
发布于 2020-07-22 12:18
大佬请收下我的膝盖
点赞
送花
回复 分享
发布于 2020-07-22 11:52
秋招专场
校招火热招聘中
官网直投
请问输入的1 2 1 2 5是什么意思呢
点赞
送花
回复 分享
发布于 2020-07-22 12:00
cpp爆搜n=10的情况也超时了
点赞
送花
回复 分享
发布于 2020-07-22 12:04
第一题是只需要输出其中一种排序即可吗?还是全部排序结果都要?
点赞
送花
回复 分享
发布于 2020-07-22 12:11
第二个题的输入数组和区间还是没有找到关系.不明白题意...
点赞
送花
回复 分享
发布于 2020-07-22 12:46
第一题输出为啥没有3 1 4 2
点赞
送花
回复 分享
发布于 2020-07-22 12:47
考试时间是60分钟吗?大佬
点赞
送花
回复 分享
发布于 2020-07-22 15:59
 你好,这个结论:对于以i结尾的区间,若j使得a[j...i]满足条件,则对j'<j,a[j&(8762)#39;...i]都满足条件。 那我们对i进行拓展,若j使得a[j...i]满足条件,则对i<i',a[j...i&#39;]都满足条件。 对左边界保持不变,右边界进行拓展,是不是也满足啊
点赞
送花
回复 分享
发布于 2020-07-22 16:31
楼主老哥。第二题可以观察规律,我没参加考试,菜鸡一枚,你看我这样对吗 const int N = 4e5 + 100; const int M = 4e5 + 100; int n,k; int a[N]; unordered_map<int,int> m; bool vis[N]; int main() {     cin >> n >> k;     for(int i = 1; i <= n; i++)     {         cin >> a[i];     }     long long sum = 0;     queue<int> dq;     for(int i = 1; i <= n; i++)     {         m[a[i]]++;         dq.push(i);         if(vis[a[i]] == false && m[a[i]] >= k)         {             cout << a[i] << endl;             sum += (n - i  + 1);         }     }     cout << sum << endl; }
点赞
送花
回复 分享
发布于 2020-07-22 18:22
第二题按照题主思路实现,测试没有问题。如果自己直接写估计惨的一批了。。。
点赞
送花
回复 分享
发布于 2020-07-22 18:27
只能考一次是吗?我参加了7.15的,显示已完成笔试
点赞
送花
回复 分享
发布于 2020-07-22 18:36
这是面试啥职位的?
点赞
送花
回复 分享
发布于 2020-07-23 02:05
哪位大佬知道笔试多少分可以过呀?
点赞
送花
回复 分享
发布于 2020-07-23 22:37
请问阿里笔试每一批题目都是一样的吗
点赞
送花
回复 分享
发布于 2020-07-23 22:42
请问这个笔试时间是可以自己选择的么?我的笔试公告没有任何信息。。
点赞
送花
回复 分享
发布于 2020-07-26 13:08
请问第一题考虑按字典序输出的条件吗?我在怀疑n=10没有ac,是因为10开头的排列应该排在1开头的排列后面
点赞
送花
回复 分享
发布于 2020-07-27 11:42
第二题暴力接法 import sys n, m = map(int, input().split()) nums = list(map(int, input().split())) ans = 0 for i in range(n):     s = set(nums[:i+1])     for x in s:         if nums[:i+1].count(x) >= m:             ans+=1 print(ans)
点赞
送花
回复 分享
发布于 2020-07-27 22:57

相关推荐

20 74 评论
分享
牛客网
牛客企业服务