题目描述:编写一个程序,输出一个数在长度为
n
n
n 的顺序表的从小到大的排名,并输出其在原顺序表中的下标 (下标从
1
1
1 开始)。输入第一行一个数
n
n
n, 表示这个顺序表的长度
(
n
≤
2
×
1
0
5
)
(n leq 2 times 10^5)
(n≤2×105)。第二行有
n
n
n 个数,表示这个顺序表中的元素,保证这些元素两两不同,但是不保证递增,注意下标从
1
1
1 开始,所有数均
≤
2
×
1
0
9
leq 2 times 10^9
≤2×109。第三行一个数
t
t
t,表示询问次数
(
t
≤
50000
)
(t leq 50000)
(t≤50000)。第四行
t
t
t 个数,表示询问的这
t
t
t 个数。输出对于每个询问,如果这个数在顺序表中存在,那么输出一行两个数,表示所查询的数在这个顺序表中的排名和在在顺序表中的原下标,如果所查询的数原顺序表中不存在,这一行只需要输出一个
−
1
-1
−1。
输入输出样例
样例输入
8
1 3 5 6 7 10 9 8
4
1 4 8 10
样例输出
1 1
-1
6 8
8 6
提示
将这些元素化为有序后是 1 3 5 6 7 8 9 10。
1
1
1 的排名为
1
1
1,原下标为
1
1
1,
4
4
4 不存在,
8
8
8 的排名为
6
6
6原下标为
8
8
8,
10
10
10 的排名为
8
8
8,原下标为
6
6
6。二分查找的前提是序列有序,但是数据不保证递增,所以你需要先排序。快速排序如果每次都选择当前区间的第一个元素作为基准的话效率是极不稳定的,并且有可能被卡到
O
(
n
2
)
O(n^2)
O(n2),应该尽量避免这种方法 (但是就本题而言,卡快速排序的数据可能并不能有效的卡掉希尔排序,并且这个测试点满足
n
≤
100000
n leq 100000
n≤100000)。对于输出原下标的功能,请考虑结构体。
#include#include #include const int maxn=(int) 2e5+10; using namespace std; struct px //结构体存原数据与下标 { int x,y; }a[maxn]; bool cmp(px a,px b) //升序排序 { return a.x =l){ int m=l+(r-l)/2; if(a[m].x==c){ flag=0; cout< a[m].x) l=m+1; else r=m-1; } } int main() { int n,t,i; cin>>n; for(i=1;i<=n;i++) { cin>>a[i].x; a[i].y=i; } sort(a+1,a+n+1,cmp); //懒人必备 cin>>t; while(t--) { int flag=1,c; cin>>c; erfen(c,1,n,flag); if(flag) cout<<"-1"<



