对于某些数据范围很大,但是分布却非常稀疏的题目,直接用数组存非常浪费空间,而且很可能会炸,于是要用到离散化这样的技巧;
其实这名字似乎很高大上,算法实现并不难,只是对数据排个序,去重,然后在其余代码部分用这个数的编号代替这个数就可以了;
实现排序和去重起来有很多种方法,用STL会更简单一些;
方法一:vector
输出:数据及其对应编号
1 #include<cstdio> 2 #include<algorithm> 3 #include<vector> 4 using namespace std; 5 const int MAXN=; 6 int n; 7 vector<int>a; 8 int main() 9 { 10 scanf("%d",&n); 11 int x; 12 for(int i=1;i<=n;++i) 13 { 14 scanf("%d",&x); 15 a.push_back(x); 16 } 17 sort(a.begin(),a.end()); 18 a.resize(unique(a.begin(),a.end())-a.begin()); 19 for(int i=0;i<n;++i)printf("%d %d ",a[i],i); 20 return 0; 21 }
方法二:set
只能输出排序后、按升序排列的数据,如果非要输出编号需要重载运算符……懒得写了
1 #include<cstdio> 2 #include<algorithm> 3 #include<set> 4 using namespace std; 5 const int MAXN=110; 6 int n; 7 set<int>a; 8 int main() 9 { 10 scanf("%d",&n); 11 int x; 12 for(int i=1;i<=n;++i) 13 { 14 scanf("%d",&x); 15 a.insert(x); 16 } 17 set<int>::iterator iter; 18 for(iter=a.begin();iter!=a.end();++iter)printf("%d ",*iter); 19 return 0; 20 }
在排序、去重之后,需要将编号映射到数,可以手写数组,也可以用map