问题CD均来自http://t.csdn.cn/mEFf6
且问题AB都为67%通过率,欢迎大佬们指正!
问题 A: 折半查找的次数(67%)
题目描述
给你一个无重复数的有序序列,如果采用折半查找的方式,对于给定的数,需要比较几次找到,请编程实现。
输入
第一行是N,表示序列中数的个数,序列最长1000,第二行是一个有序序列,第三行是要找的数x。
输出
如果找到x,输出折半比较的次数,否则输出NO。
样例输入 Copy
11 5 13 19 21 37 56 64 75 80 88 92 19
样例输出 Copy
2
#include <iostream>
using namespace std;
int Search(int A[], int key, int n) {
int low = 0;
int high = n - 1;
int mid;
while (low <= high) {
mid = (low + high) / 2;
if (key == A[mid]) {
return mid;
}
else if (key < A[mid]) {
high = mid - 1;
}
else {
low = mid + 1;
}
}
return 0;
}
void Print(int A[], int n) {
for (int i = 0; i < n; i++) {
cout << A[i] << " ";
}
cout << endl;
}
int main()
{
int n = 0;
cin >> n;
int* A = new int [n];
for (int i = 0; i < n; i++)
{
cin >> A[i];
}
int x;
cin >> x;
if (Search(A, x, n))
{
cout << Search(A, x, n);
}
else
cout << "NO";
return 0;
}
问题 B: 二叉搜索树中的查找 (67%)
题目描述
给你一个数据序列,请构造一个二叉搜索树,然后计算出找到给定数据需比较的次数。
输入
第一行是N,表示序列中数的个数,序列最长1000,第二行是一个数据序列,第三行是要找的数x。
输出
如果找到x,输出比较的次数,没找到则输出NO。
样例输入 Copy
5 1 2 3 5 4 5
样例输出 Copy
4
#include<iostream>
using namespace std;
struct Node{
int data;
Node *l=NULL,*r=NULL;
};
int count=0;
void creat(int *p,int i,Node *root)
{
if(p[i]<root->data)
{
if(root->l==NULL)
{
root->l=new Node;
root->l->data=p[i];
}
else
{
creat(p,i,root->l);
}
}
if(p[i]>root->data)
{
if(root->r==NULL)
{
root->r=new Node;
root->r->data=p[i];
}
else
{
creat(p,i,root->r);
}
}
}
int find(Node *root,int x)
{
if(x<root->data)
{
if(root->l==NULL)
return 0;
else
{
count++;
find(root->l,x);
}
}
if(x>root->data)
{
if(root->r==NULL)
return 0;
else
{
count++;
find(root->r,x);
}
}
if(x==root->data)
{
count++;
return 1;
}
}
int main()
{
int n,x;
cin>>n;
int *p=new int[n];
for(int i=0;i<n;i++)
{
cin>>p[i];
}
cin>>x;//待查找数
Node *root=new Node;
root->data=p[0];
for(int i=1;i<n;i++)//根已经赋值所以从i=1开始
{
creat(p,i,root);
}
int judge=find(root,x);
if(judge)
cout<<count;
else
cout<<"NO";
return 0;
}
问题 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>
#include<cstring>
using namespace std;
int d[30][30];
int main() {
int m,n;
cin>>m>>n;
char a,b;
int w;
memset(d,0x3f,sizeof(d));
for(int i=1;i<=m;i++) d[i][i]=0;
for(int i=1;i<=n;i++) {
cin>>a>>b>>w;
d[a-'A'+1][b-'A'+1] = w;
d[b-'A'+1][a-'A'+1] = w;
}
for(int k=1;k<=m;k++) {
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
if(d[i][k]+d[k][j]<d[i][j])
d[i][j] = d[i][k]+d[k][j];
}
cin>>a>>b;
cout<<d[a-'A'+1][b-'A'+1];
return 0;
}
问题 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<cstring>
#include<queue>
using namespace std;
struct edge {
char a,b;
int w,next;
}e[105];
int cnt,dis[105],head[105];
bool vis[105];
int pre[105];
struct node {
int w,now;
inline bool operator <(const node &x) const {
return w>x.w;
}
};
priority_queue<node> q;
void add(char a,char b,int w) {
e[++cnt].a = a;
e[cnt].b = b;
e[cnt].w = w;
e[cnt].next = head[a-'A'+1];
head[a-'A'+1] = cnt;
}
void dijkstra(char fir) {
dis[fir-'A'+1]=0;
node x = {0,fir-'A'+1};
char v;
q.push(x);
while(!q.empty()) {
x = q.top();
q.pop();
int u = x.now;
if(vis[u]) continue;
vis[u] = true;
for(int i=head[u];i;i=e[i].next) {
v = e[i].b;
if(dis[v-'A'+1]>dis[u]+e[i].w) {
dis[v-'A'+1] = dis[u]+e[i].w;
pre[v-'A'+1] = u;
x = {dis[v-'A'+1],v-'A'+1};
q.push(x);
}
}
}
}
void findPath(int a,int b) {
if(a==b) {
cout<<char(a+'A'-1)<<" ";
return;
}
findPath(a,pre[b]);
cout<<char(b+'A'-1)<<" ";
}
int main() {
int m,n;
cin>>m>>n;
char a,b;
int w;
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=n;i++) {
cin>>a>>b>>w;
add(a,b,w);
}
cin>>a>>b;
dijkstra(a);
findPath(a-'A'+1,b-'A'+1);
return 0;
}
问题 E: 5个数的从大到小排序
题目描述
数学课上,老师公布了一个小组的5名同学的成绩,你能编程把成绩从大到小排序吗,以便老师知道考试名次?
输入
5个整数,用空格间隔开。
输出
从大到小的5个数,中间用空格间隔。
样例输入 Copy
86 78 99 100 66
样例输出 Copy
100 99 86 78 66
#include<iostream>
using namespace std;
void find(int n,int s[])
{
int temp = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (s[j] < s[j + 1])
{
temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
for (int i = 0; i < n; i++)
{
cout << s[i]<<" ";
}
}
int main()
{
int n = 0;
cin >> n;
int *s = new int [n];
for (int i = 0; i < n; i++)
{
cin >> s[i];
}
find(n,s);
return 0;
}
问题 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 person
{
string id;
int year;
};
void paixu(person* s1,person* s2,int n)
{
int count=0;
for(int i=0;i<n;i++)
{
if (s1[i].year<60)
{
s2[count].year=s1[i].year;
s2[count].id=s1[i].id;
count++;
s1[i].year=-1;
}
}
int temp1=0;
string temp2;
for(int i=0;i<n;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(s1[j].year<s1[j+1].year)
{
temp1=s1[j+1].year;
s1[j+1].year=s1[j].year;
s1[j].year=temp1;
temp2=s1[j+1].id;
s1[j+1].id=s1[j].id;
s1[j].id=temp2;
}
}
}
//输出
for(int i=0;i<n;i++)
{
if(s1[i].year!=-1)
cout<<s1[i].id<<endl;
}
for(int i=0;i<count;i++)
{
cout<<s2[i].id<<endl;
}
}
int main()
{
int sum;
cin>>sum;
person s1[101];
person s2[101];
for(int i=0;i<sum;i++)
{
cin>>s1[i].id>>s1[i].year;
}
paixu(s1,s2,sum);
return 0;
}