题目描述:
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)