离散化
什么叫做离散化?就是把一个较大的数字映射成为一个较小的数字!列如给你200个1-1e100范围内的数字,那么最大1e100能否用一个1-200内的数字表示呢?答案是可以的!因为只有200个数字,那么把给出的所有数字按照输入顺序映射成为1,2…200,当然数字重复映射也会重复!
那么如何实现这部操作呢??STL中学过容器就知道,map就是映射的一种实现方式!!
以下是一个简单的离散化模板,可以得知离散化后的数字和出实现的个数
# include <bits/stdc++.h>
using namespace std;
const int N= 1e5 ;
int cnt[ N] ;
map< int , int > p, sum;
int main ( ) {
int n;
scanf ( "%d" , & n) ;
int pos= 0 ;
for ( int i= 1 ; i<= n; i++ ) {
int x;
scanf ( "%d" , & x) ;
if ( ! p[ x] ) p[ x] = ++ pos;
cnt[ i] = p[ x] ;
sum[ p[ x] ] ++ ;
}
return 0 ;
}
题目大意:请你帮忙选择一部电影,可以让观影很开心的人最多。如果有多部电影满足条件,则在这些电影中挑选观影比较开心的人最多的那一部。
思路:这道题目是一道离散化的好题,因为我们这里的语言,是非常的分散,所以我们可以把他们汇聚在一起,也就是重新定义这些语言,重新标号1,2,3,…,n。
注意:这道题目统计方面,因为时间限制非常严格,所以动用了C++11的哈希级别map,unordered_map<int,int>,优点就是在读取存入会比map快很多!!!
# include <bits/stdc++.h>
using namespace std;
const int N= 2 * 1e5 + 5 ;
struct node {
int a, b, x;
} mv[ N] ;
int per[ N] ;
unordered_map< int , int > p, sum;
bool cmp ( node x, node y) {
if ( x. a!= y. a) return x. a> y. a;
else return x. b> y. b;
}
int main ( ) {
int n;
scanf ( "%d" , & n) ;
int pos= 0 ;
for ( int i= 1 ; i<= n; i++ ) {
int x;
scanf ( "%d" , & x) ;
if ( ! p[ x] ) p[ x] = ++ pos;
per[ i] = p[ x] ;
sum[ p[ x] ] ++ ;
}
int m;
scanf ( "%d" , & m) ;
for ( int i= 1 ; i<= m; i++ ) {
int x;
scanf ( "%d" , & x) ;
x= p[ x] ;
mv[ i] . a= sum[ x] ;
}
for ( int i= 1 ; i<= m; i++ ) {
int x;
scanf ( "%d" , & x) ;
x= p[ x] ;
mv[ i] . b= sum[ x] ;
mv[ i] . x= i;
}
sort ( mv+ 1 , mv+ m+ 1 , cmp) ;
printf ( "%d\n" , mv[ 1 ] . x) ;
return 0 ;
}