题目描述:
360公司 2020秋招 技术综合C卷在线考试 编程题 | 30.0分2/2 序列重组 时间限制:C/C++语言 1000MS;其他语言 3000MS 内存限制:C/C++语言 65536KB;其他语言 589824KB 题目描述: 在一个古老的国度,这个国家的人并不懂得进位,但是对取模情有独钟,因此诞生了一个经典的问题,给出两个在m进制下含有n位的数字,你可以分别将这两个数各位上的数字重新排列,然后将两个数按位对应相加并分别对m取模,这样显然可以得到一个新的m进制下的n位数(可能存在前导0),但是这个结果是不唯一的,问题来了,按照这样的操作,能够得到的最大的m进制下的数字是多少呢。 输入 输入第一行包含两个正整数n,m分别表示数字含有n位,和在m进制下。(n,m≤100000) 输入第二行和第三行分别包含n个整数,中间用空格隔开,每个整数都在0到m-1之间。每行第i个数表示的是当前数第i位上的数字。 输出 输出包含n个数字,中间用空格隔开,表示得到的最大的数字,从高位到低位输出,如6在2进制下输出3位的结果是1 1 0。 样例输入 5 5 4 4 1 1 1 4 3 0 1 2 样例输出 4 4 3 3 2 提示 4 4 1 1 1 →1 4 1 4 1 4 3 0 1 2 →3 0 2 4 1(重排序列不唯一,数位相加后的数字为 4 4 3 8 2,对5取模即可 )
代码:
作者:Dvelpro 链接:https://www.nowcoder.com/discuss/224600?type=0&order=0&pos=17&page=1 来源:牛客网 直接暴力解,先排序,然后贪心,这题复杂度太假了,最后偶尔能过100% 有点卡常
#include<bits/stdc++.h> using namespace std; typedef long long ll; int t1[100010],t2[100010]; int tmp[100010],tot=0; int main() { int n,m;scanf("%d%d",&n,&m); multiset<int> s1,s2; for(int i=1;i<=n;i++){ int tmp;scanf("%d",&tmp);s1.insert(tmp); } for(int i=1;i<=n;i++){ int tmp;scanf("%d",&tmp);s2.insert(tmp); } for(int i=m-1;i>=0;i--){ tot=0; for(multiset<int>::iterator j=s1.begin();j!=s1.end();++j){ if(s2.find((i-(*j)+m)%m)!=s2.end()){ tmp[tot++]=*j; s2.erase(s2.find((i-(*j)+m)%m)); printf("%d ",i); } } for(int j=0;j<tot;j++){ s1.erase(s1.find(tmp[j])); } } return 0; }
代码2:
原文链接:https://blog.csdn.net/qq_18310041/article/details/99656445 import copy # m进制 m = 5 n = 5 line = [[4,4,1,1,1],[4,3,0,1,2]] res = [] count_0 = [] count_1 = copy.deepcopy(line[1]) for i in range(n): count_0.append(m - 1 - line[0][i]) for i in range(n): if line[1][i] in count_0: res.append(m-1) count_0.remove(line[1][i]) count_1.remove(line[1][i]) count_0.sort(reverse= True) count_1.sort(reverse= False) for i in range(len(count_0)): count_0[i] = m - 1 - count_0[i] t = count_0[i] + count_1[i] if t > m-1: t =t - m res.append(t) else: res.append(t) res.sort(reverse=True) print(res)