问题 A 折半查找的次数
给你一个无重复数的有序序列,如果采用折半查找的方式,对于给定的数,需要比较几次找到,请编程实现。
输入
第一行是N,表示序列中数的个数,序列最长1000,第二行是一个有序序列,第三行是要找的数x。
输出
如果找到x,输出折半比较的次数,否则输出NO。
样例输入 Copy
11
5 13 19 21 37 56 64 75 80 88 92
19
输出
2
#include<iostream>
using namespace std;
int a(int n,int *m,int val) {
int fir(0), las(n - 1), mid,time=0;
while (las >= fir) {
mid = (fir + las) / 2;
if (m[mid] == val) {
if(las!=fir)
time++;
return time;
}
if (las != fir)
time++;
if (m[mid] > val) {
las = mid - 1;
}
if (m[mid] < val) {
fir = mid + 1;
}
}
return -1;
}
int main()
{
int n; cin >>n ;
int* m = new int[n];
for (int i = 0; i < n; i++)
cin >> m[i];
int val;
cin >> val;
if (a(n, m, val) == -1)cout << "NO";
else cout << a(n, m, val);
}
问题 B 二叉搜索树中的查找
题目描述
给你一个数据序列,请构造一个二叉搜索树,然后计算出找到给定数据需比较的次数。
输入
第一行是N,表示序列中数的个数,序列最长1000,第二行是一个数据序列,第三行是要找的数x。
输出
如果找到x,输出比较的次数,没找到则输出NO。
样例输入 Copy
5
1 2 3 5 4
5
样例输出 Copy
4
#include<iostream>
using namespace std;
struct node {
node* left, * right;
int val;
node(int n = -1) {
val = n; left = right = NULL;
}
};
node* find(int val, node* p) {
if (p->left == NULL && p->val > val) { node* newnode = new node(val); p->left = newnode; return newnode; }
if (p->right == NULL && p->val < val) { node* newnode = new node(val); p->right = newnode; return newnode; }
if (p->val > val) { return find(val, p->left); }
if (p->val < val) { return find(val, p->right); }
}
node* create(int n, int* m) {
node* newnode, * root = new node, * temp;
root->val = m[0];
for (int i = 1; i < n; i++) {
newnode = find(m[i], root);
}
return root;
}
int see(int val, node* root) {
node* p = root; int time = 0;
while (p) {
if (val > p->val) {
if (p->right == NULL)break;
p = p->right; time++;
}
if (val < p->val) {
if (p->left == NULL)break;
p = p->left; time++;
}
if (val == p->val) {
time++;
return time;
}
}
return -1;
}
int main()
{
int n;
cin >> n;
int* m = new int[n];
for (int i = 0; i < n; i++)
{
cin >> m[i];
}
node* x;
x = create(n, m);
int val; cin >> val;
val = see(val, x);
if (val == -1)cout << "NO";
else cout << val;
}
问题 C 有向图的最短路径长度
题目描述
已知一个有向图,每个边都有一个正整数表示边长,请编程求出其中两个顶点间的最短路径长度。
输入
第一行是M、N,分别表示顶点数和有向边数(0<M,N<=100》),紧接着N行的每一行是X、Y、H,分别表示有向边的起点和终点以及边长。最后一行是要求其最短路径的两个顶点。
输出
相应两个顶点的最短路径值。
样例输入 Copy
5 7
A B 10
B C 50
A E 100
A D 30
C E 10
D C 20
D E 60
A E
样例输出 Copy
60
#include<iostream>
using namespace std;
int main()
{
int n, m; cin >> n >> m;
int** x;
x = new int* [n];
for (int i = 0; i < n; i++)
x[i] = new int[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
x[i][j] = 99999;
}
for (int i = 0; i < m; i++) {
char a, b; cin >> a >> b;
int val; cin >> val;
x[a - 65][b - 65] = val;
}
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (x[i][j] > x[i][k] + x[k][j])
x[i][j] = x[i][k] + x[k][j];
char a, b; cin >> a >> b;
cout << x[a - 65][b - 65];
}
问题 D 有向图的最短路径
题目描述
已知一个有向图,每个边都有一个正整数表示边长,请编程求出其中两个顶点间的最短路径长度。
输入
第一行是M、N,分别表示顶点数和有向边数(0<M,N<=100》),紧接着N行的每一行是X、Y、H,分别表示有向边的起点和终点以及边长。最后一行是要求其最短路径的两个顶点。
输出
相应两个顶点的最短路径经过的顶点序列。
样例输入 Copy
5 7
A B 10
B C 50
A E 100
A D 30
C E 10
D C 20
D E 60
A E
样例输出 Copy
A D C E
#include<iostream>
#include<string>
using namespace std;
int quan[500][500];
const int max = 1000;
int main()
{
int n, m;
cin >> n >> m;//顶点和边长
int** x;//权值和边
string** y;
x = new int* [n],y=new string*[n];
for (int i = 0; i < n; i++) {
x[i] = new int[n];
y[i] = new string[n];
}
for(int i=0;i<n;i++)
for (int j = 0; j < n; j++) {
x[i][j] = 9000;
y[i][j] = char(i + 65);
}
for (int i = 0; i < m; i++) {
char a, b;
cin >> a >> b;
int val; cin >> val;
x[a - 65][b - 65] = val;
}
//算法:弗洛伊德算法
for (int k = 0; k <n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (x[i][j] > x[i][k] + x[k][j]) {
x[i][j] = x[i][k] + x[k][j];
y[i][j] += ' ';
y[i][j] += char(k+65);
}
char p, q; cin >> p >> q;
cout << y[p - 65][q - 65]<<' '<<q;
}
问题 E 5个数的从大到小排序
题目描述
数学课上,老师公布了一个小组的5名同学的成绩,你能编程把成绩从大到小排序吗,以便老师知道考试名次?
输入
5个整数,用空格间隔开。
输出
从大到小的5个数,中间用空格间隔。
样例输入 Copy
86 78 99 100 66
样例输出 Copy
100 99 86 78 66
#include<iostream>
#include<string>
using namespace std;
struct je {
string id; int age,fla;
je(){}
je(je &x) {
id = x.id;
age = x.age;
fla = x.fla;
}
};
int main() {
int x[5];
for (int i = 0; i < 5; i++)
cin >> x[i];
for(int i=0;i<5;i++)
for (int j = 0; j < 4-i ; j++) {
if(x[j]>x[j+1]){
int temp(x[j]);
x[j] =x[j + 1];
x[j + 1] = temp;
}
}
for (int i = 0; i < 5; i++)
cout << x[i] << ' ';
}
问题 F 病人排队
病人登记看病,编写一个程序,将登记的病人按照以下原则排出看病的先后顺序:
1.老年人(年龄 >= 60岁)比非老年人优先看病。
2.老年人按年龄从大到小的顺序看病,年龄相同的按登记的先后顺序排序。
3.非老年人按登记的先后顺序看病。
输入
第1行,输入一个小于100的正整数,表示病人的个数;
后面按照病人登记的先后顺序,每行输入一个病人的信息,包括:一个长度小于10的字符串表示病人的ID(每个病人的ID各不相同且只含数字和字母),一个整数表示病人的年龄,中间用单个空格隔开。
输出
按排好的看病顺序输出病人的ID,每行一个。
样例输入 Copy
5
021075 40
004003 15
010158 67
021033 75
102012 30
样例输出 Copy
021033
010158
021075
004003
102012
#include<iostream>
#include<string>
using namespace std;
struct je {
string id; int age,fla;
je(){}
je(je &x) {
id = x.id;
age = x.age;
fla = x.fla;
}
};
int main() {
int n;
cin >> n;
je *s;
s = new je[n];
for (int i = 0; i < n; i++) {
cin >> s[i].id >> s[i].age;
if (s[i].age < 60)s[i].fla = 0;
else s[i].fla = s[i].age;
}
for(int i=0;i<5;i++)
for (int j = 0; j < 4; j++) {
if(s[j].fla<s[j+1].fla){
je temp(s[j]);
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
for (int i = 0; i < n; i++) {
cout << s[i].id << endl;
}
}