Description
给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始
要求使用顺序索引查找算法,其中索引表查找和块内查找都采用不带哨兵、从头开始的顺序查找方法。
Input
第一行输入n,表示主表有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入k,表示主表划分为k个块,k也是索引表的长度
第四行输入k个数据,表示索引表中每个块的最大值
第五行输入t,表示有t个要查找的数值
第六行起,输入t个数值,输入t行
Output
每行输出一个要查找的数值在队列的位置和查找次数,数据之间用短划线隔开,如果查找不成功,输出字符串error
Sample
#0
Input
Copy
18 22 12 13 8 9 20 33 42 44 38 24 48 60 58 74 57 86 53 3 22 48 86 6 13 5 48 40 53 90
Output
Copy
3-4 error 12-8 error 18-9 error
思路:
本题给出一串序列,并将其分成几块,给出每块中的最大值,然后我们查找的时候,只要在其中一块中查找就好了
如:A块中最大值为22,B块中最大值为50,那如果查找30的时候,30>A最大值20,30<=B最大值50,所以就在B块中查找了
样例:
1.先分块
![](https://i-blog.csdnimg.cn/blog_migrate/e53f5a8a6b6a2bc3007150269ade67b6.png)
2.开始查找:
一:简单点先看在第一块里的:
查找13,13<=22,所以在第一块里,然后在第一块中查找
然后在第一块里找到
查找次数:找在第一块里花了1次查找次数,然后在第一块里找到他从左往右找,找了三次,所以次数总共是4次
二.查找的值的大小在块里,但是那一块里面却没有这个值:
按照大小比较,5<=22,在第一块里,然后查找第一块,第一块里面没有他,所以输出error
三.查找的值存在且在别的块里:
48>22,48<=48,在第二块里(与第一块最大值比较一次是查了一次,与第二块最大值比较一次是第二次)
在第二块最后一个,查找了六次
查找次数:2+6=8
4.查找的值根本不在块里:
90>22,90>48,90>86,不在任何一块里面,所以根本没这个值,输出error
代码细节:
1.分块的处理
![](https://i-blog.csdnimg.cn/blog_migrate/d5d7b9747879e1a38aabf075a5a7e88f.png)
2.分块的每一块的范围的处理
![](https://i-blog.csdnimg.cn/blog_migrate/359ee4421504c2125264f240f386f7cc.png)
3.查找
一:查找在第几块
二:查找在第几块中的第几个位置
tips:flag=1表示查找到了
全部代码:
#include <iostream>
using namespace std;
const int maxn = 1e3 + 10;
int shuzu[maxn];///存所有数据
struct nmax
{
int val;///存取最大值
int end;///存取最大值的一部分的最大下标,就是那一块的终点,这一块的起点是前一块终点+1
///如 1 2 5 3 4 7 8 10 9
//分成两块,最大值分别为5 ,10
//第一块就是 1 2 5 3 4,假设下标从1开始,那第一部分的最大下标就是5,指向4
};
nmax maxshuzu[maxn];//存取每一块的最大值
int main()
{
int n;
while (cin >> n)
{
for (int i = 1; i <= n; i++)///输出数据
{
cin >> shuzu[i];
}
int m;
cin >> m;///输入分成m块
for (int i = 1; i <= m; i++)
{
cin >> maxshuzu[i].val;///输入每一块中的最大值
}
maxshuzu[0].end = 0;
shuzu[n + 1] = 0x3f3f3f;///这里在最后添加一个无穷大
//我们确定块的范围是大于前一块的地方作为起点,第一个大于这一块的最大值的-1作为终点
///如 1 2 5 3 4 7 8 10 9 0x3f3f3f
//分成两块,最大值分别为5 ,10
//第二块的位置在7开始,7是第一个大于前一块最大值5,作为起点
//我们第二块就不知道终点,所以在尾巴放一个无穷大的数,终点就是第一个大于第二块最大值10的位置-1,指向9
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n+1; j++)
{
if (shuzu[j] > maxshuzu[i].val)//找到大于这一块的最大值的第一个点
{
maxshuzu[i].end = j - 1;
break;
}
}
}
int t;
cin >> t;///输入查找t次
while (t--)
{
int num;
int cnt = 0;///cnt负责统计查找次数
int flag = 0;///flag状态变量判断是否查找到了
cin >> num;
///先找在第几块里
int i;///i表示在第几块
for (i = 1; i <= m; i++)
{
cnt++;
if (num <= maxshuzu[i].val)
{
break;///找到在第i块里
}
}
if (i > m)///i>m表面不在块里,那就没有这个数
{
cout << "error" << endl;
continue;
}
int j;//j表示在第i块里第j个位置
///在前一块的终点+1作为起点,终点是自己的这一块的末位置
for (j = maxshuzu[i - 1].end + 1; j <= maxshuzu[i].end; j++)
{
cnt++;
if (shuzu[j] == num)
{
flag = 1;
break;
}
}
if (flag)
{
cout << j << "-" << cnt << endl;//j就是数据在数组里的下标
}
else
{
cout << "error" << endl;
}
}
}
}
今天就到这吧!
再见再见再见!!!