上图转自新浪微博:“阿里代码库有几亿行代码,但其中有很多功能重复的代码,比如单单快排就被重写了几百遍。请设计一个程序,能够将代码库中所有功能重复的代码找出。各位大佬有啥想法,我当时就懵了,然后就挂了。。。”
这里我们把问题简化一下:首先假设两个功能模块如果接受同样的输入,总是给出同样的输出,则它们就是功能重复的;其次我们把每个模块的输出都简化为一个整数(在 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
题目虽长,实际意思非常简单,简单来说就是读入一段数据,然后统计这一段数据出现的次数,然然后按照出现次数的降序进行排序,然后这里特别说明一下并列的时候的情况。我们就拿题目给出的样例 1 11 66 0 1 28 74 35 他们出现的次数都是一次,并列了,但是为什么11 66 0会排在28 74 35的前面,那是因为根据数中的升序 11<28所以 28 74 35会排列在11 66 0的前面。好的现在我们已经理解题目的意思了 来讲讲题目的思路:
首先看到要统计出现的次数,我们会非常容易的想到用map,用map的key来储存那段数据,value来储存出现的次数 ,然后现在的问题就是这一段数据我们需要用什么储存,一开始我想使用string来当key记录这段数据,因为这样会方便很多,但是当我写完之后,我发现如果出现并列的情况,string这段数据(但是这样可以拿到18分 有两个测试点拿不到)并不好判断哪个在前面哪个在后面(举个例子:754 9 5 和99 8 1 那这样排序的时候string会把754那一串排在前面因为(7<9)这样就错了) 所以这里我们只能使用vector来当key :
map<vector<int> ,int> c;
然后把数据放进去,注意在为空的时候要初始化一下:
int n,x,a;
cin>>n>>x;
map<vector<int> ,int> c;
vector<int> temp;//临时vector读取
for(int i = 0;i<n;i++){
for(int j = 0;j<x;j++){
cin>>a;
temp.push_back(a);
}
if(c.count(temp)==0) c[temp] = 1;//判断是不是存在,不存在就初始化一下
else c[temp]++;
temp.clear();//用完临时数组要记得清空
}
好,现在我们已经把所有的数据他们出现的次数都已经存起来了,这时候就要进行排序,但是sort排序在vector并不适用,所以我们这里需要把map转化为vector,在利用sort进行排序:
vector<pair<vector<int> ,int>> re(c.begin(),c.end());
写出比较器:先利用value排序。如果value相等就在利用key排序,这里的key是vector在里边他会自动取出vector的值一个一个来进行判断:
bool cmp(pair<vector<int> ,int> a,pair<vector<int> ,int> b){
if(a.second!=b.second) return a.second>b.second;
else return a.first<b.first;
}
排序:
sort(re.begin(),re.end(),cmp);
然后再输出的时候要注意因为re的key是vector,不可以直接用re.first进行直接访问,需要开一个临时vector来存储这个key,再给他输出出来:
vector<int> temp2;
cout<<re.size()<<endl;
for(int i = 0;i<re.size();i++){
cout<<re[i].second;
temp2 = re[i].first;
for(int j = 0;j<temp2.size();j++) cout<<" "<<temp2[j];
temp2.clear();
cout<<endl;
}
整体完成代码:
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<vector<int> ,int> a,pair<vector<int> ,int> b){
if(a.second!=b.second) return a.second>b.second;
else return a.first<b.first;
}
int main()
{
int n,x,a;
cin>>n>>x;
map<vector<int> ,int> c;
vector<int> temp;
for(int i = 0;i<n;i++){
for(int j = 0;j<x;j++){
cin>>a;
temp.push_back(a);
}
if(c.count(temp)==0) c[temp] = 1;
else c[temp]++;
temp.clear();
}
vector<pair<vector<int> ,int>> re(c.begin(),c.end());
sort(re.begin(),re.end(),cmp);
vector<int> temp2;
cout<<re.size()<<endl;
for(int i = 0;i<re.size();i++){
cout<<re[i].second;
temp2 = re[i].first;
for(int j = 0;j<temp2.size();j++) cout<<" "<<temp2[j];
temp2.clear();
cout<<endl;
}
return 0;
}