销售网站排名网站运营培训
目录
A: 快速排序
B: 随机数
C: 随机化快速排序
D: 第k小元素问题
E: 找中位数
F: 数的划分
G: 带分数
H: 最大质因数
A: 快速排序
编程实现快速排序算法,深入理解快速排序算法的基本思想。
输入
多组输入,每组第一个数字为数组长度,然后输入一个一维整型数组。
输出
输出快速排序之后的一维整型数组(升序)
样例输入 Copy
6 1 8 6 5 3 4 5 12 42 2 5 8样例输出 Copy
1 3 4 5 6 8 2 5 8 12 42
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N];
void quick_sort(int a[], int l, int r)
{if (l >= r)return;int x = a[(l + r + 1) / 2], i = l - 1, j = r + 1;while (i < j){do{i++;} while (a[i] < x);do{j--;} while (a[j] > x);if (i < j)swap(a[i], a[j]);}quick_sort(a, l, i - 1);quick_sort(a, i, r);
}
int main()
{int n;while (~scanf("%d", &n)){for (int i = 0; i < n; i++)scanf("%d", &a[i]);quick_sort(a, 0, n - 1);for (int i = 0; i < n; i++)printf("%d ", a[i]);cout << endl;}return 0;
}
B: 随机数
有一个rand(n)的函数,它的作用是产生一个在[0,n)的随机整数。现在有另外一个函数,它的代码如下:
int random(int n, int m)
{
return rand(n)+m;
}
显而易见的是函数random(n,m)可以产生任意范围的随机数。现在问题来了,如果我想要产生范围在[a,b)内的一个随机数,那么对应的n,m分别为多少?
输入
输入的第一行为一个正整数T (T<=1000),表示一共有T组测试数据。
对于每组测试数据包含两个整数a,b (a<=b)。
输出
对于每组测试数据,输出一行包含两个整数n和m,两个整数中间有一个空格分隔。
样例输入 Copy
2 0 5 1 4样例输出 Copy
5 0 3 1
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int N =1e4 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
void solve(){int n,a,b;cin>>n;while(n--){cin>>a>>b;cout<<b-a<<" "<<a<<"\n";}
}
int main() {ios::sync_with_stdio(0);cin.tie(0);//int t;cin>>t;while(t--)solve();return 0;
}
C: 随机化快速排序
使用Java或C++等语言中内置的随机函数实现随机化快速排序,在数组中随机选择一个元素作为分区的主元(Pivot)。
输入
多组样例输入,每组由一个一维整型数组组成。
输出
随机化快速排序之后的一维整型数组(升序排列)。
样例输入 Copy
6 1 8 6 5 3 4 5 12 42 2 5 8样例输出 Copy
1 3 4 5 6 8 2 5 8 12 42
#include <iostream>
using namespace std;
const int N = 100002;
int a[N];
void quick_sort(int q[], int l, int r)
{if (l >= r)return;int m = rand() % (r - l + 1) + l;swap(q[l], q[m]);int x = q[l];int i = l - 1, j = r + 1;while (i < j){doi++;while (q[i] < x);doj--;while (q[j] > x);if (i < j)swap(q[i], q[j]);}quick_sort(q, l, j);quick_sort(q, j + 1, r);
}
int main()
{int n;while (~scanf("%d", &n)){for (int i = 0; i < n; ++i)scanf("%d", &a[i]);quick_sort(a, 0, n - 1);for (int i = 0; i < n; ++i)cout << a[i] << " ";cout << endl;}return 0;
}
D: 第k小元素问题
输入一个整数数组,请求出该数组的第k小元素。要求时间复杂度为O(n)。
输入
每组输入包括两行,第一行为一个整数数组,两个数字之间用空格隔开;第二行为k值。数组中元素个数小于1000。
输出
输出第k小元素的值。
样例输入 Copy
2 5 6 1 8 7 9 2样例输出 Copy
2
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int N =1e3 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
int a[N];
int k;
int fun(int l,int r,int k){if(l==r){return a[l];}int i=l;for(int j=l+1;j<=r;j++){if(a[j]<=a[l]){swap(a[++i],a[j]);}}swap(a[i],a[l]);int m=i-l+1;if(k<=m){fun(l,i,k);}else{fun(i+1,r,k-m);}
}
void solve(){int n=0;char c,cc;while(cin>>a[0]){scanf("%c",&c);if(c!='\n'){for(n=1;;n++){cin>>a[n];scanf("%c",&cc);if(cc=='\n'){break;}}}int k;cin>>k;cout<<fun(0,n,k)<<"\n";}
}
int main() {//ios::sync_with_stdio(0);cin.tie(0);//int t;cin>>t;while(t--)solve();return 0;
}
E: 找中位数
请设计一个算法,不排序,快速计算出一个无序数列的中位数。 时间复杂度要求为O(n)。
如果有奇数个元素,中位数则是数组排序后最中间的那个数字。
如果是偶数个元素,中位数则是数组排序后最中间两个元素的平均值。输入
有多组输入,每组输入的第一行为n(1<=n<=1e5),表示该数列的元素个数。
第二行为n个整数组成的无序数列输出
每组样例输出一行,表示该无序数列的中位数。
若为偶数,请保留三位小数
若为奇数,直接输出样例输入 Copy
5 5 3 2 1 4样例输出 Copy
3
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <map>
#include <iomanip>
#include <queue>
#define ll long long
#define MM 0x3f3f3f3f
#define pii pair<int, int>
#define pll pair<long long, long long>
using namespace std;
const int N = 1e3 + 5;
const int P = 131;
const int MOD=1e9+7;
const double PI = acos(-1.0);
//int dx[] = {0, 0, -1, 1,-1, -1, 1, 1};
//int dy[] = {1, -1, 0, 0,1, -1, 1, -1};
int n;
void fun(vector<int>& a){nth_element(a.begin(),a.begin()+n/2,a.end());if(n%2==1){cout<<a[n/2]<<"\n";} else{nth_element(a.begin(),a.begin()+n/2-1,a.end());printf("%.3lf\n",0.5*(a[n/2-1]+a[n/2]));}
}
void solve(){while(cin>>n){vector<int>a(n);for(int i=0;i<n;i++){cin>>a[i];}fun(a);}
}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);solve();return 0;
}
F: 数的划分
使用递归编写一个程序,求一个正整数n的所有划分个数。
例如,输入3,输出3;输入4,输出5。输入
多组输入,每一组是一个正整数n。
输出
输出划分数。
样例输入 Copy
3 4样例输出 Copy
3 5
#include<iostream>
using namespace std;
int fun(int n,int m)
{if (n == 1 || m == 1)return 1;if (n > m)return fun(n - m, m) + fun(n, m - 1);elseif (n < m)return fun(n, n);elsereturn fun(n, n-1)+1;
}
int main()
{int n;while (cin >> n)cout << fun(n,n) << endl;return 0;
}
G: 带分数
100可以表示为带分数的形式,如100 = 3+ 69258/714,还可以表示为100 = 82 + 3546/197。
注意,在上述带分数的形式中,数字1,2,3,4,5,6,7,8,9均出现一次并只能出现一次。
类似这种带分数形式,100一共有11种表示方法。输入
单组输入。
输入一个不超过10000的正整数N。输出
输出该数字用1-9九个数字不重复且不遗漏地组成带分数形式表示的全部方法的数量。
样例输入 Copy
100样例输出 Copy
11
#include <stdio.h>
#include <string.h>
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int fun(int l, int r) {int s = 0;for (int i = l; i <= r; i++) {s = s * 10 + a[i];}return s;
}
void swap(int *x, int *y) {int temp = *x;*x = *y;*y = temp;
}
int next_permutation(int *arr, int n){int i = n - 2;while (i >= 0 && arr[i] >= arr[i + 1]) i--;if (i < 0) return 0;int j = n - 1;while (arr[j] <= arr[i]) j--;swap(&arr[i], &arr[j]);int left = i + 1, right = n - 1;while (left < right) {swap(&arr[left], &arr[right]);left++;right--;}return 1;
}
void solve() {int n;scanf("%d", &n);int s = 0;do {for (int i = 0; i < 6; i++) {for (int j = i + 1; j <= 7; j++) {int x = fun(0, i);int y = fun(i + 1, j);int z = fun(j + 1, 8);if (y % z == 0 && x + y / z == n) {s++;}}}} while (next_permutation(a, 9));printf("%d\n", s);
}
int main() {solve();return 0;
}
H: 最大质因数
自然数中任何一个合数都可以表示成若干个质因数乘积的形式,如果不考虑因数的顺序,那么这个表示形式是唯一的。
把一个合数分解成几个质数相乘的形式,叫做分解质因数,这几个质数就叫做这个合数的质因数。例如,60=2×2×3×5,2024=2×2×2×11×23。所有的质因数中最大者称为最大质因数。
请编写一个程序输出一个合数的最大质因数。输入
单组输入。
输入一个不超过10^9的合数N。输出
输出该合数的最大质因数。
样例输入 Copy
2024样例输出 Copy
23
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int M =1e9 +7;
const int N =1e2 +5;
int a[N];
void solve(){int n;cin>>n;int m=0;for(int i=2;i<=sqrt(n);i++){if(n%i==0){a[++m]=i;while(n%i==0){n/=i;}}}if(n>1){a[++m]=n;}cout<<a[m]<<"\n";
}
int main() {cin.tie(0)->sync_with_stdio(false);solve();return 0;
}