上图转自新浪微博:“阿里代码库有几亿行代码,但其中有很多功能重复的代码,比如单单快排就被重写了几百遍。请设计一个程序,能够将代码库中所有功能重复的代码找出。各位大佬有啥想法,我当时就懵了,然后就挂了。。。”
这里我们把问题简化一下:首先假设两个功能模块如果接受同样的输入,总是给出同样的输出,则它们就是功能重复的;其次我们把每个模块的输出都简化为一个整数(在 int 范围内)。于是我们可以设计一系列输入,检查所有功能模块的对应输出,从而查出功能重复的代码。你的任务就是设计并实现这个简化问题的解决方案。
输入格式:
输入在第一行中给出 2 个正整数,依次为 N(≤104)和 M(≤102),对应功能模块的个数和系列测试输入的个数。
随后 N 行,每行给出一个功能模块的 M 个对应输出,数字间以空格分隔。
输出格式:
首先在第一行输出不同功能的个数 K。随后 K 行,每行给出具有这个功能的模块的个数,以及这个功能的对应输出。数字间以 1 个空格分隔,行首尾不得有多余空格。输出首先按模块个数非递增顺序,如果有并列,则按输出序列的递增序给出。
注:所谓数列 { A1, ..., AM } 比 { B1, ..., BM } 大,是指存在 1≤i<M,使得 A1=B1,...,Ai=Bi 成立,且 Ai+1>Bi+1。
输入样例:
7 3
35 28 74
-1 -1 22
28 74 35
-1 -1 22
11 66 0
35 28 74
35 28 74
输出样例:
4
3 35 28 74
2 -1 -1 22
1 11 66 0
1 28 74 35
代码长度限制
16 KB
Java (javac)
时间限制
1500 ms
内存限制
128 MB
Python (python3)
时间限制
1500 ms
内存限制
64 MB
其他编译器
时间限制
500 ms
内存限制
64 MB
分析:1、vector接受功能模块
2、结构体将功能模块和出现次数捆绑
3、map记录已出现模块在结构体数组中的下标
4、按题目规则进行排序输出
#include<bits/stdc++.h>
using namespace std;
int m;
struct xx{//因为排序规则,需要将两个信息捆绑,所以需要用到结构体
vector<int> mk;
int cs=0;
};
bool com(xx a,xx b){
if(a.cs!=b.cs) return a.cs>b.cs;
else for(int i=0;i<m;i++){
if(a.mk[i]!=b.mk[i]) return a.mk[i]<b.mk[i];
}
}
map<vector<int>,int> mpx;//记录已出现的功能模块的下标
int main(){
int n,j=0,a;//j为新出现的功能模块分配下标
cin>>n>>m;
xx s[n];
for(int i=0;i<n;i++){
vector<int> b;//存储当前需要输入的功能模块
for(int k=0;k<m;k++){
cin>>a;
b.push_back(a);
}
if(mpx.find(b)==mpx.end()){//没有出现过的功能模块,将它记录并且为它分配一个下标
s[j].mk=b;
mpx[b]=j++;
}
s[mpx[b]].cs++;//将当前模块出现次数加1
}
sort(s,s+j,com);//排序
cout<<j<<endl;
for(int i=0;i<j;i++){
cout<<s[i].cs;
for(int k=0;k<m;k++){
cout<<' '<<s[i].mk[k];
}
cout<<endl;
}
return 0;
}