算法1
借助map统计次数,并构建结构体
方法1:借助map,以及使用结构体存储m序列的语音和字幕的取值。主要用于统计每种语言出现的次数,然后后续两遍m遍历
第一轮遍历找出每个语音序列位置,对应的语言在n中的最大个数,并记录位置,第二遍遍历,从
等于上面最大个数的位置中找出字幕序列中元素在语言序列中较大的那个
C++ 代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#define N 200010
using namespace std;
map<int,int>s;
int a[N];
int b[N];
struct zz
{
int a;
int b;
}p[N];
int main()
{
int n,m,i,j,k;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
//s用来统计a[i]的个数
s[a[i]]++;
}
scanf("%d",&m);
for(i=1;i<=m;i++)
scanf("%d",&p[i].a);
for(i=1;i<=m;i++)
scanf("%d",&p[i].b);
int mm=0;k=1;
for(i=1;i<=m;i++)
{
//统计出现次数最多的语言的个数,并记录其在语音列表中---第一次出现-----的位置
if(mm<s[p[i].a])
{
mm=s[p[i].a];
k=i;
}
}
//统计
int kk=0;
for(i=1;i<=m;i++)
{
//在mm相等的情况下,比较s[p[i].b]。记录s[p[i].b]最大的位置
if(s[p[i].a]==mm)
{
if(kk<s[p[i].b])
{
kk=s[p[i].b];
k=i;
}
}
}
printf("%d\n",k);
return 0;
}
所谓的排序和离散化:其实就是将n序列和m序列中的所有可能都映射到一个数组中,然后利用该数组进行排序
和去重,然乎再利用一些二分查找去计数,感觉“离散化”这操作没啥意思,多此一举了~
C++ 代码
//方法2,离散化的思想
#include<bits/stdc++.h>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2e5+5;
int n,m;
int a[maxn],b[maxn],c[maxn];
int sum[maxn*3];
int cnt,mm;
int arr[maxn*3],num[maxn*3];
void discrete(){//离散化
sort(arr+1,arr+cnt+1);
for(int i=1;i<=cnt;i++){
if(i==1||arr[i]!=arr[i-1])
num[++mm]=arr[i];
}
}
int query(int x){//二分查找x的位置
return lower_bound(num+1,num+mm+1,x)-num;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){//将所有电影和人涉及的语言放进一个数组,排序并离散化
scanf("%d",&a[i]);
arr[++cnt]=a[i];
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&b[i]);
arr[++cnt]=b[i];
}
for(int i=1;i<=m;i++){
scanf("%d",&c[i]);
arr[++cnt]=c[i];
}
discrete();//离散化
//离散化以后,将所有的语言的坑都填起来
for(int i=1;i<=n;i++){
int id=query(a[i]);//统计每种语言的人的数量
//sum数组类似于map使用,统计n序列中数字的出现个数
//所以这样看来,还不如直接用map,不用扯什么排序和离散化
++sum[id];
}
int bmax=-1,cmax=-1,ans=0;
for(int i=1;i<=m;i++){//选择满足题目要求的电影
int x=query(b[i]);
int y=query(c[i]);
if(sum[x]>bmax){//优先考虑让很高兴的人最多
bmax=sum[x],cmax=sum[y];
ans=i;
}else {
//否则if是在相等的情况下,则我们可以
if(sum[x]==bmax&&sum[y]>cmax){//如果答案不唯一、则在此前提下再让比较高兴的人最多
bmax=sum[x],cmax=sum[y];
ans=i;
}
}
}
printf("%d\n",ans);
return 0;
}
为什么k要付初值1?
这个代码写的太漂亮了
%%%
大佬,int id=query(a[i]);//统计每种语言的人的数量这句话什么意思呢
id为离散化后语言 a[i] 在 num 数组中出现的位置(其实相当于语言的重新分类),同种语言的 id(位置)一样的,且同种语言 a[i] 在循环中出现的次数即为该种语言的人数,所以用 sum 数组来统计
第一个代码会超时
输入换成scanf会快一些
离散化的话,在 n足够大 的时候会有优势的吧。线性结构进行随机访问+二分会比直接用树或者Hash好
讲的真好,谢谢大佬。