深圳大学计软《数据结构》实验12--静态查找

问题 A: DS静态查找之顺序查找

题目描述

给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始

要求使用带哨兵的顺序查找算法

输入

第一行输入n,表示队列有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入t,表示有t个要查找的数值
第四行起,输入t个数值,输入t行

输出

每行输出一个要查找的数值在队列的位置,如果查找不成功,输出字符串error

样例输入

8
33 66 22 88 11 27 44 55
3
22
11
99

样例输出

3
5
error

AC代码

#include <iostream>
#include<vector>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int>v(n + 1);
	for (int i = 1; i <= n; i++)
		cin >> v[i];
	int t;
	cin >> t;
	while (t--)
	{
		int value;
		cin >> value;
		int index = n;
		while (index)
		{
			if (v[index] == value)
				break;
			index--;
		}
		if (index)
			cout << index << endl;
		else
			cout << "error" << endl;

	}
	return 0;
}

问题 B: DS静态查找之折半查找

题目描述

给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始

要求使用折半查找算法

输入

第一行输入n,表示队列有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入t,表示有t个要查找的数值
第四行起,输入t个数值,输入t行

输出

每行输出一个要查找的数值在队列的位置,如果查找不成功,输出字符串error

样例输入

8
11 22 33 44 55 66 77 88
3
22
88
99

样例输出

2
8
error

AC代码

#include <iostream>
#include<vector>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int>v(n + 1);
	for (int i = 1; i <= n; i++)
		cin >> v[i];
	int t;
	cin >> t;
	while (t--)
	{
		int value;
		cin >> value;
		int low = 1, hign = n;
		int mid;
		bool flag = 0;
		while (low <= hign)
		{
			mid = (low + hign) / 2;
			if (v[mid] == value)
			{
				cout << mid << endl;
				flag = 1;
				break;
			}

			if (v[mid] > value)
				hign = mid - 1;
			else
				low = mid + 1;
		}
		if (!flag)
			cout << "error" << endl;
	}

	return 0;
}

问题 C: DS静态查找之顺序索引查找

题目描述

给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始

要求使用顺序索引查找算法,其中索引表查找和块内查找都采用不带哨兵、从头开始的顺序查找方法。

输入

第一行输入n,表示主表有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入k,表示主表划分为k个块,k也是索引表的长度
第四行输入k个数据,表示索引表中每个块的最大值
第五行输入t,表示有t个要查找的数值
第六行起,输入t个数值,输入t行

输出

每行输出一个要查找的数值在队列的位置和查找次数,数据之间用短划线隔开,如果查找不成功,输出字符串error

样例输入

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

样例输出

3-4
error
12-8
error
18-9
error

AC代码

#include<iostream>
using namespace std;
#include<vector>

int main() {
	int n, t;
	cin >> n;
	vector<int>v(n);
	for (int i = 0; i < n; i++)
		cin >> v[i];
	cin >> t;
	vector<int>index(t);
	for (int i = 0; i < t; i++)
		cin >> index[i];

	int round;
	cin >> round;
	while (round--)
	{
		int cnt = 0;
		int value;
		cin >> value;
		int range = -1;
		for (int i = 0; i < t; i++)
		{
			cnt++;
			if (value <= index[i])
			{
				range = i;
				break;
			}
		}

		if (range == -1)
		{
			cout << "error" << endl;
			continue;
		}

		bool ok = 0;
		for (int i = range * n / t; i < (range + 1) * n / t; i++)
		{
			cnt++;
			if (v[i] == value)
			{
				cout << i + 1 << "-" << cnt << endl;
				ok = 1;
				break;
			}
		}

		if (!ok)
			cout << "error" << endl;
	}
	return 0;
}

问题 D: DS查找——折半查找求平方根

题目描述

假定输入y是整数,我们用折半查找来找这个平方根。在从0到y之间必定有一个取值是y的平方根,如果我们查找的数x比y的平方根小,则x2<y,如果我们查找的数x比y的平方根大,则x2>y,我们可以据此缩小查找范围,当我们查找的数足够准确时(比如满足|x2-y|<0.00001),就可以认为找到了y的平方根。

比如求5的平方根x,则x一定满足 0<=x<=5,取x为(5+0)/2=2.5,因为2.5的平方为6.25>5,所以x一定小于2.5,也即x满足0<=x<=2.5,取x为1.25,以此类推

…
…

最后求得5的平方根为2.236
温馨提示: 计算过程中为确保精确性,计算变量的类型都用double
保留小数位数请采用printf(“%.3lf\n”,x) 的格式输出
程序框架参考平时练习中折半查找的方法

输入

第1行输入一个整数n(<100),表示有n个数
从第2行起到第n+1行输入n个整数

输出

输出n个数的平方根,精确到小数点后三位。

样例输入

2
13
5

样例输出

3.606
2.236

AC代码

#include <iostream>
using namespace std;

double get_sqrt(const double n)
{
	static double presicion = 0.0001;
	double low = 0, hign = n;
	double mid;
	while (hign - low > presicion)
	{
		mid = (hign + low) / 2;
		if (mid * mid == n)
			return mid;
		if (mid * mid > n)
			hign = mid;
		else
			low = mid;
	}
	return mid;
}



int main() {
	int n;
	cin >> n;
	while (n--)
	{
		double t;
		cin >> t;
		printf("%.3lf\n", get_sqrt(t));
	}
	return 0;
}

问题 E: 无线网络 (Ver. I)

题目描述

在东南亚发生了地震。 ACM(Asia Cooperated Medical team)已经用笔记本建立了无线网络,但是由于一次余震,网络中的所有计算机都损坏了。 计算机一个接一个地修复,网络逐渐开始工作。 由于硬件限制,每台计算机只能直接与距离它不远的计算机进行通信。 但是,每台计算机都可以被视为两台计算机之间通信的中介,也就是说,如果计算机A和计算机B可以直接通信,计算机C可以与计算机A进行通信,则计算机C和计算机B可以进行通信。

在修复网络的过程中,工作人员先后进行两种操作,先修复计算机,再测试两台计算机是否可以通信。 你的任务是回答所有的测试操作。

输入

输入数据只有一组

第一行包含两个整数N和d(1 <= N <= 100,0 <= d <= 20000)。 这里N是计算机的数量,编号从1到N,D是两台计算机可以直接通信的最大距离。 在接下来的N行中,每行包含两个整数xi,yi(0 <= xi,yi <= 10000),这是N台计算机的坐标。 从第(N + 1)行到输入结束,有一些操作,这些操作是一个接一个地执行的。 每行包含以下两种格式之一的操作:

1.“O p”(1 <= p <= N),修复计算机p
2.“S p q”(1 <= p,q <= N),测试计算机p和q是否可以通信

其中所有的修复操作都在测试操作之前

输入不会超过3000行

输出

对于每个测试操作,如果两台计算机可以通信则输出“SUCCESS”,否则输出“FAIL”。

样例输入

4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 2
S 1 4
S 1 3
S 2 3

样例输出

SUCCESS
FAIL
FAIL
FAIL

AC代码

#include<iostream>
using namespace std;
#include<cmath>
#include<vector>

//并查集
class Myset {
	vector<int>parent;
	vector<bool>ok;
public:
	Myset(int n = 0) {
		parent.resize(n);
		for (int i = 0; i < n; i++)
			parent[i] = i; 
		ok.resize(n);
	}

	int FindSet(int x) {
		if (x != parent[x])
			parent[x] = FindSet(parent[x]);
		return parent[x];
	}

	void Union(int index1, int index2)
	{
		int root1 = FindSet(index1);
		int root2 = FindSet(index2);
		if (root1 == root2)
			return;
		parent[root1] = root2;
	}

	bool isOk(int index) { return ok[index]; }
	void repair(int index) { ok[index] = 1; }

};

double is_connect(int x1, int y1, int x2, int y2, int distance)
{
	return pow(x1 - x2, 2) + pow(y1 - y2, 2) <= distance * distance;
}



int main() {

	int n, min_distance;
	cin >> n >> min_distance;
	Myset set(n);
	vector<int>x(n), y(n);
	for (int i = 0; i < n; i++)
		cin >> x[i] >> y[i];

	string s;
	while (cin >> s)
	{
		if (s == "O")
		{
			int index;
			cin >> index;
			set.repair(index - 1);

			for (int i = 0; i < n; i++)
			{
				if (index - 1 == i)
					continue;
				if (set.isOk(i) && is_connect(x[index - 1], y[index - 1], x[i], y[i], min_distance))
					set.Union(i, index - 1);
			}

		}

		else if (s == "S")
		{
			int i, j;
			cin >> i >> j;
			if (set.FindSet(i - 1) == set.FindSet(j - 1))
				cout << "SUCCESS" << endl;
			else
				cout << "FAIL" << endl;
		}
	}


	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曹无悔

请支持我的梦想!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值