A:随机数
题目描述
有一个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 <bits/stdc++.h>
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);
solve();
return 0;
}
B:随机化快速排序
题目描述
使用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)
{
do
i++;
while (q[i] < x);
do
j--;
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;
}
C:第k小元素问题
题目描述
输入一个整数数组,请求出该数组的第k小元素。要求时间复杂度为O(n)。
输入
每组输入包括两行,第一行为一个整数数组,两个数字之间用空格隔开;第二行为k值。数组中元素个数小于1000。
输出
输出第k小元素的值。
样例输入 Copy
2 5 6 1 8 7 9 2样例输出 Copy
2
#include <bits/stdc++.h>
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() {
solve();
return 0;
}
D:找中位数
题目描述
请设计一个算法,不排序,快速计算出一个无序数列的中位数。 时间复杂度要求为O(n)。
如果有奇数个元素,中位数则是数组排序后最中间的那个数字。
如果是偶数个元素,中位数则是数组排序后最中间两个元素的平均值。输入
有多组输入,每组输入的第一行为n(1<=n<=1e5),表示该数列的元素个数。
第二行为n个整数组成的无序数列输出
每组样例输出一行,表示该无序数列的中位数。
若为偶数,请保留三位小数
若为奇数,直接输出样例输入 Copy
5 5 3 2 1 4样例输出 Copy
3
#include <bits/stdc++.h>
#define ll long long
#define MM 0x3f3f3f3f
using namespace std;
const int N = 1e3 + 5;
const int P = 131;
const int MOD=1e9+7;
const double PI = acos(-1.0);
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;
}
E: 数组合并
题目描述
编写一个程序,将两个有序数组合并成一个更大的有序数组,要求时间复杂度为O(n)。
输入
多组数据输入,每组输入包括两行,每行第一个数字为数组长度n,然后输入n个有序整数。
输出
输出合并后的数组(升序),每组输出用一个空行隔开。
样例输入 Copy
3 1 3 5 3 2 4 6 2 1 2 4 3 4 5 6样例输出 Copy
1 2 3 4 5 6 1 2 3 4 5 6
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N =1e3 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
int a[N],b[N],c[N];
void solve(){
int n;
while(cin>>n){
for(int i=0;i<n;i++){
cin>>a[i];
}
int m;
cin>>m;
for(int i=0;i<m;i++){
cin>>b[i];
}
int i=0,j=0,z=0;
while(i<n&&j<m){
if(a[i]<=b[j]){
c[z++]=a[i++];
}
else{
c[z++]=b[j++];
}
}
while(i<n){
c[z++]=a[i++];
}
while(j<m){
c[z++]=b[j++];
}
for(int i=0;i<z;i++){
cout<<c[i]<<" ";
}
cout<<"\n\n";
}
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}
F:归并排序
题目描述
编写一个程序,使用分治策略实现二路归并排序(升序)。
输入
多组输入,每组第一个数字为数组长度,然后输入一个一维整型数组。
输出
输出排序之后(升序)的一维整型数组,每组输出占一行。
样例输入 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 <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N =1e3 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
int a[N], t[N], n;
void merge_sort(int a[], int l, int r)
{
if (l == r)
return;
int mid = (l + r) / 2, i = l, j = mid + 1, k = 0;
merge_sort(a, l, mid);
merge_sort(a, mid + 1, r);
while (i <= mid && j <= r)
if (a[i] <= a[j])
t[k++] = a[i++];
else
t[k++] = a[j++];
while (i <= mid)
t[k++] = a[i++];
while (j <= r)
t[k++] = a[j++];
for (i = l, j = 0; i <= r; i++, j++)
a[i] = t[j];
}
void solve(){
while (cin >> n)
{
for (int i = 0; i < n; i++)
cin >> a[i];
merge_sort(a, 0, n - 1);
for (int i = 0; i < n; i++)
{
cout << a[i];
if (i < n - 1)
cout << ' ';
else
cout << "\n";
}
}
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}
G:最长匹配括号子串
题目描述
给定一个只包含尖括号"<"和">",小括号"("和")",中括号"["和"]",花括号"{"和"}"这八种符号的字符串(长度>=1)。
在字符串中括号可以任意嵌套,如果对应的左、右括号成对出现并且嵌套正确,则为一对可匹配括号。
匹配括号子串是指在一个括号串的一个子串(可以包含这个括号串自身)中,每一个括号都是可匹配括号。
编写一个程序计算一个输入字符串中最长匹配括号子串的长度。输入
单组输入。
输入一个只包含上述八种左、右括号的字符串。(1≤ 字符串长度≤105)输出
输出输入字符串中最长匹配括号子串的长度。
样例输入 Copy
<[({})][]()}{<>样例输出 Copy
10
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N =1e3 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
void solve(){
string a;
cin>>a;
stack<int> st;
st.push(-1);
int s=0;
for(int i=0;i<a.size();i++){
if(a[i]=='('||a[i]=='['||a[i]=='{'||a[i]=='<'){
st.push(i);
}
else{
if(!st.empty()&&((a[st.top()]=='('&&a[i]==')')||(a[st.top()]=='['&&a[i]==']')||(a[st.top()]=='{'&&a[i]=='}')||(a[st.top()]=='<'&&a[i]=='>'))){
st.pop();
s=max(s,i-st.top());
}
else{
st.push(i);
}
}
}
cout<<s<<"\n";
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}
H:人民币转换(虽然过了,但是题目数据肯定有问题)
题目描述
考试题目和要点:
1、中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。
2、中文大写金额数字到“元”为止的,在“元”之后,应写“整字,如¥ 532.00应写成“人民币伍佰叁拾贰元整”。在”角“和”分“后面不写”整字。
3、阿拉伯数字中间有“0”时,中文大写要写“零”字,阿拉伯数字中间连续有几个“0”时,中文大写金额中间只写一个“零”字,如¥6007.14,应写成“人民币陆仟零柒元壹角肆分“。
输入
多组输入。输入一个double数。
输出
输出人民币格式。
样例输入 Copy
151121.15样例输出 Copy
人民币拾伍万壹仟壹佰贰拾壹元壹角伍分提示
10.56 读作人民币拾元伍角陆分
30005007 读作 三千万五千零七
30025007 读作 三千零二万五千零七
30020507 读作 三千零二万零五百零七
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N =1e3 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
string s[]={"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾"};
string fun(int n){
if(n<=10){
return s[n];
}
else if(n<100){
return (n/10!=1?fun(n/10):"")+"拾"+(n%10?fun(n%10):"");
}
else if(n<1000){
if(n%100==0){
return fun(n/100)+"佰";
}
else{
return fun(n/100)+"佰"+((n%100)<10?"零":"")+(fun(n%100));
}
}
else if(n<10000){
if(n%1000==0){
return fun(n/1000)+"仟";
}
else{
return fun(n/1000)+"仟"+((n%1000)<100?"零":"")+(fun(n%1000));
}
}
else if(n<100000000){
if(n%10000==0){
return fun(n/10000)+"万";
}
else {
return fun(n/10000)+"万"+((n%10000)<1000?"零":"")+(fun(n%10000));
}
}
else{
if(n%100000000==0){
return fun(n/100000000)+"亿";
}
else{
return fun(n/100000000)+"亿"+((n%100000000)<10000000?"零":"")+(fun(n%10000000));
}
}
}
string fun1(int n){
if(n==0){
return "整";
}
else if(n<10){
return s[n]+"分";
}
else{
return s[n/10]+"角"+(n%10?fun1(n%10):"");
}
}
void solve(){
string c;
while(cin>>c){
if(c.find(".")!=string::npos){
int x=c.find(".");
string aa=c.substr(0,x);
string bb=c.substr(x+1,c.size());
int a=stoi(aa);
int b=stoi(bb);
if(a==0){
cout<<"人民币"<<fun1(b)<<"\n";
}
else{
cout<<"人民币"<<fun(a)<<"元"<<fun1(b)<<"\n";
}
}
else{
int a=stoi(c);
int b=0;
cout<<"人民币"<<fun(a)<<"元"<<fun1(b)<<"\n";
}
}
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}