首页 > 其他分享 >P2249 【深基13.例1】查找题解

P2249 【深基13.例1】查找题解

时间:2024-02-17 21:12:52浏览次数:27  
标签:11 10 13 int 题解 复杂度 深基 查找

【问题分析】
本题有n个数(n > 10^6)n很大, 查找m 个数(m≤10^5) ,数最大为(10^9)

方法一:用顺序查找的话时间复杂度为:O(n * m)会超时, 只能得部分分;

方法二:用桶排时间复杂度为O(n)+ O(m),但是因为数最大为(109)空间复杂度为:O(109);

方法三:用二分查找,时间复杂度为:O(m * log n),空间复杂度为O(n)。
综合以上的时间复杂度和空间复杂度,我们选用方法三。

【设计程序】

方法一:

#include<bits/stdc++.h>
using namespace std;
int const N = 1e6 + 5;//数组要开大一点
int a[N];
int n, m;
int find(int x)//查找此数的位置
{
	for(int i = 1;i <= n; i++)
		if (a[i] == x)//第一次遇到x时返回位置
			return i;
	return -1;//如果没找到
}
int main()
{
	int x;
	scanf ("%d%d", &n, &m);
	for (int i = 1;i <= n; i++)
		scanf ("%d", a + i);//输入数列
	for (int i = 1;i <= m; i++)
	{
		scanf ("%d", &x);//输入要查找的数
		printf ("%d ", find(x));//输出位置
	}
	return 0;
}//据检测全部TLE

方法二:
肯定超空间,所以此处不写。

方法三:

#include<bits/stdc++.h>
using namespace std;
int const N = 1e6 + 5;//数组要开大一点
int a[N];
int n, m;
int find(int x)//查找此数的位置
{
	int l = 1, r = n;//左右位置
	while (l <= r)
	//注:此写法中l和r在未查找过的数上
	{
		int m = (l + r) >> 1;//找中间位置
		if (a[m] < x)	l = m + 1;//判断
		else	r = m - 1;
	}
	if (a[l] == x)//如果找到
		return l;
	return -1;//如果没找到
}
int main()
{
	int x;
	scanf ("%d%d", &n, &m);
	for (int i = 1;i <= n; i++)
		scanf ("%d", a + i);//输入数列
	for (int i = 1;i <= m; i++)
	{
		scanf ("%d", &x);//输入要查找的数
		printf ("%d ", find(x));//输出位置
	}
	return 0;
}

【代码调试】

  1. 测试样例

  2. 自测数据(边界值,特殊值,本题中为第一个,最后一个,有重复,找不到)

自测(本题测试样例中已有第一个,有重复,找不到,只需再加最后一个即可):

输入:
11 4
1 3 3 3 5 7 9 11 13 15 17
1 3 6 17

输出:
1 2 -1 11

标签:11,10,13,int,题解,复杂度,深基,查找
From: https://www.cnblogs.com/Assassins-Creed/p/18018411

相关文章

  • P8248 简单数列 题解
    首先,圈重点:$1\len\le500$所有元素在$1\sim4$之间任意连续的连续子串不相同只要输出一种答案即可于是我们可以得到的是:由第一点和第二点可以看出此题可以写搜索解决。由第三点我们可以得到一种剪枝方式,就是如果目前数字放入后会产生相同的连续的连续子串。由第四点......
  • P1380 T型骨牌 题解
    本题每个位置有$5$种可能,据题中$n,m$均小于五,所以可以用搜索直接过。上代码#include<cstdio>usingnamespacestd;boolmp[15][15];intn,m,ans;intdt[4][5][2]={{{-1,-1},{0,-1},{1,-1},{0,0},{0,1}},{{-1,0},{0,0},{1,-1},{1,0},{1,1}},{{0,......
  • P1686 挑战 题解
    本题就是要找到最短的捷径。注意事项:捷径必须是直线。要求捷径最短而非总路程最短。捷径不与原有的路重合既然在同一直线上,则该捷径的起点与终点的横坐标或纵坐标相等。要把横坐标或纵坐标相同的聚在一起只需要排个序即可。捷径最短的话(以横坐标相等举例),只需要以$x$为第......
  • P1541 [NOIP2010 提高组] 乌龟棋题解
    有两种方法,代码注释都很详细了直接上代码一:记忆化搜索#include<bits/stdc++.h>usingnamespacestd;intt[15];intn,m;inta[400];intmp[45][45][45][45];//mp[i][j][k][l]表示1号用i张,2号用j张,3号用k张,4号用l张的情况下,最多能拿多少分intdfs(intstep,intw)//step......
  • TopCoder SRM478C RandomApple 题解
    题意:有\(k\)种苹果和\(n\)个箱子,每个箱子中有一些苹果,先等概率选取\(n\)个箱子组成集合的非空子集,再从选出的苹果中随机选一个,问每种苹果被选中的概率是多少箱子\(i\)有\(a_{i,j}\)个第\(j\)种苹果,第\(i\)个箱子的总苹果数\(siz_i=\sum\limits_{j=1}^ka_{i,j}\),苹果总数\(sum=\su......
  • 洛谷P6138 [IOI2012] 骑马比武竞赛
    洛谷传送门分析首先可以将骑士比赛这件事视为将一段区间缩为一个点。那么最后剩下的一段区间中每个点一定是有一个区间浓缩而来。展开这个区间,展开后的区间中的每个点也是由一个区间浓缩而来。这样逐步展开,会得到原本的有\(n\)个元素的数组。注意,虽然迟到的还没有加入,但是各区......
  • 无限酒店 题解
    题目链接由于间隔不变,对于下面\(3\)个操作,只需记录起始位置与间隔即可。对于无数人到达酒店:所有位置的起始点\(\times2\),间隔\(\times2\),新的团队起始点为\(1\),间隔为\(2\)。对于\(k\)个人到达酒店:所有点的起始点\(+k\),间隔不变,新的团队起始点为\(0\),间隔为\(1\)......
  • Poj 3134 Power Calculus(IDA*)
    3134--PowerCalculus(poj.org)相当于是问1经过多少次能变成n,val[pos]<<(depth-now)为估计函数,如果最快都不能到n,就returnfalse#include<iostream>usingnamespacestd;constintN=1010;intn,pos,val[N];boolIDAstar(intnow,intdepth){if(now>depth)return......
  • P1136 迎接仪式
    本题只有必要对j和z进行最多m次交换,也就是重新编排序列,通过记录跟原序列有何差别来保证m次交换。可以维护\(f[i][k_1][k_2][0/1]\)表示在第1到i位中把\(k_1\)个'j'换成了'z',\(k_2\)个'z'换成了'j',最后一位是'j'还是'z'(为了转移时计数)。这时总共进行了\(k_1+k_2\)次操作,第1~i位中......
  • CF1365G Secure Password 题解
    Description本题是交互题。有一个固定的数组\(A\),同时通过数组\(A\)构造出数组\(P\),具体来讲,\(P_i\)是\(A\)中除\(A_i\)外的所有元素的按位或。你需要在最多\(13\)次询问中得到最后的\(P\)数组。\(2\leqn\leq1000\)。Solution首先有一个\(2\logn\)的是注......