3.3
题目:
用归并排序算法对两组数组排序:
- ( 32,15,14,15,11,17,25,51 )
- (12,25,17,19,51,32,45,18,22,37,15 )
解题方法:基础的归并排序算法
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e3 + 10;
int ans[maxn],tmp[maxn];
void Merge(int SortArr[], int TmpArr[], int begin, int mid, int end) {
int i = begin;
int j = mid + 1;
int k = begin;
while((i <= mid) && (j <= end)) {
if(SortArr[i] < SortArr[j]) {
TmpArr[k] = SortArr[i];
i++;
k++;
} else {
TmpArr[k] = SortArr[j];
j++;
k++;
}
}
while(i <= mid) TmpArr[k++] = SortArr[i++];
while(j <= end) TmpArr[k++] = SortArr[j++];
for(int i = begin; i <= end; i++) {
SortArr[i] = TmpArr[i];
}
return;
}
void Merge_Sort(int SortArr[], int TmpArr[], int begin, int end) {
int midIndex = 0;
if(begin < end) {
midIndex = begin + (end - begin)/2;
Merge_Sort(SortArr, TmpArr, begin, midIndex);
Merge_Sort(SortArr, TmpArr, midIndex+1, end);
Merge(SortArr, TmpArr, begin, midIndex, end);
}
}
int main() {
int t, n;
cin>>t;
while(t--){
memset(ans,0,sizeof(int));
memset(tmp,0,sizeof(int));
cin>>n;
for(int i = 1; i <= n; i++) {
cin>>ans[i];
}
Merge_Sort(ans,tmp,1,n);
for(int i = 1; i <= n; i++) {
if(i == 1) cout<<ans[i];
else cout<<" "<<ans[i];
}
cout<<endl;
}
return 0;
}
样例输入:
2
8
32 15 14 15 11 17 15 51
11
12 25 17 19 51 32 45 18 22 37 15
样例输出:
11 14 15 15 15 17 32 51
12 15 17 18 19 22 25 32 37 45 51
输出展示:
3.4
题目:
使用快速排序算法对三组数组分别排序:
1.( 24,33,24,45,12,12,24,12 )
2.( 3,4,5,6,7 )
3.(23,32,27,18,45,11,63,12,19,16,25,52,14 )
解题方法:基本的快速排序算法
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e3 + 10;
int ans[maxn];
void Quick(int SortArr[], int begin, int end) {
if(begin > end) return;
int i = begin;
int j = end;
int tmp = SortArr[begin];
while(i != j) {
while(SortArr[j] >= tmp && j > i) {
j--;
}
while(SortArr[i] <= tmp && j > i) {
i++;
}
if(j > i) {
int num = SortArr[i];
SortArr[i] = SortArr[j];
SortArr[j] = num;
}
}
SortArr[begin] = SortArr[i];
SortArr[i] = tmp;
Quick(SortArr, begin, i-1);
Quick(SortArr, i+1, end);
return;
}
int main() {
int t, n;
cin>>t;
while(t--){
memset(ans,0,sizeof(int));
cin>>n;
for(int i = 1; i <= n; i++) {
cin>>ans[i];
}
Quick(ans,1,n);
for(int i = 1; i <= n; i++) {
if(i == 1) cout<<ans[i];
else cout<<" "<<ans[i];
}
cout<<endl;
}
return 0;
}
样例输入:
3
8
24 33 24 45 12 12 24 12
5
3 4 5 6 7
13
23 32 27 18 45 11 63 12 19 16 25 52 14
样例输出:
12 12 12 24 24 24 33 45
3 4 5 6 7
11 12 14 16 18 19 23 25 27 32 45 52 63
输出展示:
3.5
题目:
“金块问题”:老板有一袋金块(共n块,n是2的幂(n≥2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。
解题方法:采用分治方法,将一条数据分为左边与右边两个部分。在寻找最大数的时候,不断的进行划分,一直划分到单个数字即左边标记与右边标记为一个数字,此时开始回溯,每次回溯都进行比较大小,每一层返回的数都为该层最小或者最大的数字,直到回到第一层即回溯结束,返回结果
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e3 + 10;
int FindMin(int arr[],int l,int r) {
if(l == r) return arr[l];
int mid,lMin,rMin;
mid = l + (r - l) / 2;
lMin = FindMin(arr, l, mid);
rMin = FindMin(arr, mid + 1, r);
return (min(lMin, rMin));
}
int FindMax(int arr[],int l,int r) {
if(l == r) return arr[l];
int mid,lMax,rMax;
mid = l + (r - l) / 2;
lMax = FindMax(arr, l, mid);
rMax = FindMax(arr, mid + 1, r);
return (max(lMax, rMax));
}
int main()
{
int n,maxx,minn;
int arr[maxn];
int t;
cin>>t;
while(t--) {
memset(arr,0,sizeof(int));
cin>>n;
for(int i = 1; i <= n; i++) cin>>arr[i];
if(n == 1) {
maxx = minn = arr[1];
} else if(n == 2) {
maxx = max(arr[1],arr[2]);
minn = (arr[1] + arr[2]) - maxx;
} else if(n >= 3) {
maxx = FindMax(arr, 1, n);
minn = FindMin(arr, 1, n);
}
cout<<maxx<<" "<<minn<<endl;
}
return 0;
}
样例输入:
3
5
1 2 3 9 5
10
9 8 5 6 4 7 1 2 3 10
8
23 45 89 12 16 14 77 61
样例输出:
9 1
10 1
89 12
输出展示:
3.6
题目:
"二分检索问题”:假定在A[1…9]中顺序存放这九个数: -7,-2,0,5,16,43,57,102,291,要求检索291,16,101是否在数组中。给定已排好序的n个元素A1, A2, A3, … An,找出元素x是否在A中。如果x在A中,指出它在A中的位置;否则,显示“没找到!”。
解题方法:基本的二分查找
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e3 + 10;
int arr[maxn];
int Find(int arr[], int begin, int end, int mark){
while(begin <= end) {
int mid = begin + (end - begin) / 2;
if(arr[mid] > mark) end = mid - 1;
else if(arr[mid] < mark) begin = mid + 1;
else return mid;
}
return -1;
}
int main() {
int m, n, num;
cin>>n;
for(int i = 1; i <= n; i++) {
cin>>arr[i];
}
cin>>m;
while(m--) {
cin>>num;
int index = Find(arr,1,n,num);
cout<<index<<endl;
}
return 0;
}
样例输入:
10
11 22 33 44 55 66 77 88 99 100
3
55
99
101
样例输出:
5
9
-1
输出展示:
3.10
题目:
利用分治法计算二叉树中分支结点的个数。
解题方法:首先明白二叉树的基本概念
- 分枝结点:度不为0的结点
- 节点的度指的是结点拥有的子树的数目,在二叉树中节点的度小于等于2
即该题为求一个二叉树拥有多少叶子节点
采用分治回溯的方法,首先通过分治分别查看每个子树,然后通过回溯记录每个子树拥有的叶子节点数进行累加。最后得到答案
代码如下:
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 1e3 + 10;
vector <int> G[maxn];
int index[maxn],number;
int Find(int root) {
int sum = 0;
int sonRoot = G[root].size();
if(sonRoot == 0) {
index[++number] = root;
return 1;
}
for(int i = 0; i < G[root].size(); i++) {
int v = G[root][i];
if(v == 0) continue;
sum = sum + Find(v);
}
return sum;
}
int main() {
int n,x,l,r;
cin>>n;//一共有n组数据,每组数据中存在x,l,r;l与r为节点x的左右节点,如果节点为空则为0
for(int i = 1; i <= n; i++) {
cin>>x>>l>>r;
G[x].push_back(l);
G[x].push_back(r);
}
int ans = Find(1);
cout<<ans<<endl;
for(int i = 1; i <= number; i++) {
cout<<index[i]<<" ";
}
return 0;
}
样例输入:
7
1 2 3
2 4 5
4 8 9
8 0 12
3 6 7
7 10 11
10 13 0
样例输出:
6
12 9 5 6 13 11
输出展示: