题目描述
DL 算缘分算得很烦闷,所以常常到体育馆去打保龄球解闷。因为他保龄球已经打了几十年了,所以技术上不成问题,于是他就想玩点新花招。
DL 的视力真的很不错,竟然能够数清楚在他前方十米左右每个位置的瓶子的数量。他突然发现这是一个炫耀自己好视力的借口——他看清远方瓶子的个数后从某个位置发球,这样就能打倒一定数量的瓶子。
-
◯◯◯◯◯◯
-
◯◯◯ ◯◯◯◯ ◯
-
◯◯
-
◯ ◯◯ ◯
如上图,每个 “◯◯” 代表一个瓶子。如果 DL 想要打倒 33 个瓶子就在 11 位置发球,想要打倒 44 个瓶子就在 22 位置发球。
现在他想要打倒 mm 个瓶子。他告诉你每个位置的瓶子数,请你给他一个发球位置。
输入格式
第一行包含一个正整数 nn,表示位置数。
第二行包含 nn 个正整数 aiai ,表示第 ii 个位置的瓶子数,保证各个位置的瓶子数不同。
第三行包含一个正整数 QQ,表示 DL 发球的次数。
第四行至文件末尾,每行包含一个正整数 mm,表示 DL 需要打倒 mm 个瓶子。
输出格式
共 QQ 行。每行包含一个整数,第 ii 行的整数表示 DL 第 ii 次的发球位置。若无解,则输出 00。
输入输出样例
输入 #1复制
5 1 2 4 3 5 2 4 7
输出 #1复制
3 0
样例解释:查找两个数:4和7,4在第三个位置出现,而7从未出现,输出0。
说明/提示
【数据范围】
对于 50%50% 的数据,1≤n,Q≤1000,1≤ai,m≤10的五次方1≤n,Q≤1000,1≤ai,m≤10的五次方。
对于 100%100% 的数据,1≤n,Q≤100000,1≤ai,m≤10的9次方1≤n,Q≤100000,1≤ai,m≤10的9次方。
题解:
首先我们考虑的是暴力,来看最简单的代码:
#include <bits/stdc++.h>
using namespace std;
int n;
int a[100010];
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
int q;
cin>>q;
for(int i=0;i<q;i++)
{
int x;cin>>x;
bool flag=true;
for(int j=0;j<n;j++)
{
if(a[j]==x)
{
cout<<j+1<<endl;
flag=false;
}
}
if(flag) cout<<0<<endl;
}
return 0;
}
恭喜你写出了代码,不过此题数据太肉了,双重循环的时间复杂度就会飙升100亿。QWQ~~~~~~
那么,正片开始!
正解:
方法一:STL大法!
众所周知,map是个好东西,它可以通过变量的映射帮我们解决一大堆问题。推荐:大佬map详解
我们先定义一个map数组,把的数值与编号互相映射。在输入查找的数时,直接调用map输出编号,千言万语不如你们想要的代码:
#include <bits/stdc++.h>
using namespace std;
map<int,int> mp;
int n;
int a[100010];
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
mp[a[i]]=i+1;
}
int q;
cin>>q;
for(int i=0;i<q;i++)
{
int x;
cin>>x;
cout<<mp[x]<<endl;
}
return 0;
}
这样,就可以快乐AC了!那么接下来……
方法二:二分
二分算法是人尽皆知的,不过人尽皆会用,恐怕做不到。不过贴心得我又准备了大佬的详解:二分详解
OK详解你们肯定看过了吧,接下来,我来帮你们梳理一下:
首先使用结构体存储,不会有人不会结构体吧。
然后,我们就使用二分查找来得出答案:
#include<bits/stdc++.h>
using namespace std;
struct pos{
int num;
int sum;
}a[100005];
bool cmp(pos x,pos y)
{
return x.sum <y.sum;
}
int main(){
int n,m,q;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].sum ;
a[i].num= i;
}
sort(a+1,a+1+n,cmp);
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>q;
int l=1,r=n,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(a[mid].sum<=q)
{
l=mid+1;
ans=mid;
}
else
{
r=mid-1;
}
}
if(a[ans].sum==q) cout<<a[ans].num<<endl;
else cout<<0<<endl;
}
return 0;
好了这就是这道题的题解,大家看懂了不要忘记点赞关注一下吧。