セッション
C:古典的な離散化問題
離散化は、データの数が多すぎて配列ストレージの範囲を超える場合にデータを最適化するために使用される方法です。現時点でこれらのデータの相対的な位置またはサイズの関係のみが必要な場合は、特定の値が不要な場合に離散値を採用できます。方法。
例:5、21,955555555;これらの3つの数値は、サイズの関係のみを考慮します。
相対位置関係の
離散化の特定のステップを表すために、1、2、3と書くことができますa [i]元の配列lsh [i]離散変換された配列cntは、数値を記録するために使用
されます。3つのステップに分かれています
。1
。データを格納した後にソートします。2。ソートされた配列に対して一意の重複排除を実行します。一意は、削除するのではなく、配列の後ろに重複要素のみを配置することに注意してください
3. low_bound関数を使用したバイナリ検索
int lsh[];int cnt;
sort(lsh + 1,lsh + 1 + cnt);
cnt = unique(lsh + 1,lsh + 1 + cnt) - lsh - 1;返回的数据的个数
low_bound(lsh + 1,lsh + 1+ cnt, x ) - lsh;// 即可找到数据的相对位置
Codeforces 670C映画の視聴:古典的な離散化ソート
コードの実装プロセス:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
// 数据离散化 的经典 题目
using namespace std;
typedef long long ll;
const int N = 2e5;
int num[3*N];int lsh[3*N];int cnt;
int a[N],b[N],c[N];// num数组用来存放离散化后的答案 lsh数组来存放离散化数据 cnt用来记录离散化数据的个数
int n,m;
void d()//离散化数据
{
cnt = 0;
for(int i = 1;i <= n;i ++)
lsh[++cnt] = a[i];
for(int i = 1;i <= m;i ++)
lsh[++cnt] = b[i];
for(int i = 1;i <= m;i ++)
lsh[++cnt] = c[i];
sort(lsh+1,lsh+cnt+1);// 把数据 从小到大排序之后 才能进行 去重操作
cnt = unique(lsh+1,lsh+1+cnt) - lsh - 1;//此时cnt记录得就是 最终 完成离散化之后 留有的数据个数 别忘了最后减一
}
int tofind(int n)
{
return lower_bound(lsh+1,lsh+1+cnt,n) - lsh;// 二分查找 离散化之后的数据位置
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i = 1;i <= n;i ++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i = 1;i <= m;i ++)
{
scanf("%d",&b[i]);
}
for(int i = 1;i <= m;i ++)
{
scanf("%d",&c[i]);
}
d();
for(int i = 1;i <= n;i ++)
num[tofind(a[i])]++;//记录个数
int num1;int num2;
int pos = 1;
int nm1;int nm2;
nm1 = nm2 = 0;
for(int i = 1;i <= m;i ++)
{
num1 = num[tofind(b[i])];
num2 = num[tofind(c[i])];
if(nm1 < num1 || (nm1 == num1 && nm2 < num2))
{
nm1 = num1;
nm2 = num2;
pos = i;// 电影院的位置
}
}
printf("%d\n",pos);
}
return 0;
}
这个题为什么 lsh 数组 要把a,b,c全部放入而不是单独放入a
我的理解是 数据的输入时并不一定会保持一致 应该存入的是全部的数据
(好吧 其实还是不是很懂qwq)```