1:
求最大公约数
【问题描述】求两个自然数m和n的最大公约数。
【评分标准】答案正确性及计算时间
#include<iostream>
using namespace std;
int CommFactor(int m, int n);
int main()
{
int a, b, r;
cin>>a>>b;
r = CommFactor(a, b);
cout<<r<<endl;
return 0;
}
int CommFactor(int m, int n)
{
int r;
r = m % n;
while(r!=0)
{
m = n;
n = r;
r = m % n;
}
return n;
}
2:
n个重复数字求和问题
【问题描述】设计程序,该程序通过键盘输入获得整型数据a和n,计算sum=a+aa+aaa+...(共计n项),输出计算结果。
【输入形式】整形数据a和n,用空格隔开
【输出形式】求和结果
【样例输入】5 4
【样例输出】6170
【样例说明】如a=5,n=4,sum=5+55+555+5555
#include <cstdio>
//求和函数
int getSum(int a,int n){
int sum=0,last=a;
for(int i=0;i<n;i++){
sum+=a;
//a+=a*10;
a=a*10+last;//每次乘以10 加上末尾的数
}
return sum;
}
int main(){
int a,n;
scanf("%d %d",&a,&n);
int result=getSum(a,n);//调用求和函数
printf("%d",result);
return 0;
}
求第k大的数
【问题描述】
求n个整数中第k大的数
【输入形式】
第一行输入n和k,第二行为n个整型数,都以空格分开
【输出形式】
第k大的数
【样例输入】
10 3
18 21 11 26 12 2 9 33 43 28
【样例输出】
28
【评分标准】
正确性与计算性能
#include <cstdio>
#include <malloc.h>
#include <search.h>
//快排cmp
//int cmp(const void *a,const void *b){
// return *(int*)a - *(int*)b;
//}
void QuickSort(int a[],int l,int r)
{
int i,j,key;
i=l;
j=r;
key=a[l]; //将第一个数作为基准数
while(i<j)
{
while(i<j && key<=a[j]) //从数组后面开始,如果大于基准数,则跳过
{
j--;
}
if(i<j) //找到第一个小于基准数的数,覆盖基准数的位置
{
a[i++]=a[j];
}
while(i<j && key>a[i]) //从数组前面开始,如果小于基准数,则跳过
{
i++;
}
if(i<j) //找到第一个大于等于基准数的数,覆盖基准数的位置
{
a[j--]=a[i];
}
}
a[i]=key;
if(l<i-1)
{
QuickSort(a,l,i-1);
}
if(r>i+1)
{
QuickSort(a,i+1,r);
}
}
int main(){
int n,k;
scanf("%d %d",&n,&k);
int *ans=(int*)malloc(sizeof(int)*n);//定义一个数组空间ans
for(int i=0;i<n;i++){
scanf("%d",&ans[i]);//依次存入数组
}
// 选择排序法
// for(int i=0;i<n;i++){
// int minno=i;
// for(int j=i+1;j<n;j++){
// if(ans[j]<ans[minno]){
// minno=j;
// }
// }
// int temp=ans[minno];
// ans[minno]=ans[i];
// ans[i]=temp;
// }
// for(int i=0;i<n;i++){
// printf("%d ",ans[i]);
// }
// printf("\n");
QuickSort(ans,0,n-1);
printf("%d",ans[n-k]);//打印结果
return 0;
}
3:
整数排序
【问题描述】
从标准输入中输入一组互不相同的整数(个数不超过100)及排序方式,按照从小到大排序,输出按某种算法排序的结果及元素的比较次数。
【输入形式】
首先在屏幕上输入1个整数,表示待排序的整数个数,然后在下一行依次输入待排序的整数。各整数之间都以一个空格分隔。
【输出形式】
在一行上输出排序结果,各整数间以一个空格分隔。
【样例1输入】
10
46 65 -9 100 0 21 2 90 8 18
【样例1输出】
-9 0 2 8 18 21 46 65 90 100
【评分标准】
该题要求按照指定算法对输入的数据进行排序。程序语言可选C或C++。
#include <iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;
int main(){
//输入n和待排序数组
int n;
cin>>n;
int *input=(int*)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
cin>>input[i];
}
//选择排序
for(int i=0;i<n-1;i++){
int index=i;
for(int j=i+1;j<n;j++){
if(input[j]<input[index]){
index=j;//record the min index
}
}
//交换记录
if(index!=i){
int t=input[i];
input[i]=input[index];
input[index]=t;
}
}
//输出结果
for(int i=0;i<n;i++){
if(i==n-1){
cout<<input[i];//输出样式注意点
}
else{
cout<<input[i]<<" ";
}
}
return 0;
}
最近点对
【问题描述】输入若干个二维点,横纵坐标分别依次存储于数组x, y中,请合理设计算法求出最近点对,并输出这个最近的距离。
【填写说明】
请阅读上下文并在空格处填入缺失代码。
最后距离的开方计算保留小数点后三位即可,提示:可采用二分查找实现。
【评分标准】结果正确的情况下结合计算时间排行获得相应分数。
#include<iostream>
using namespace std;
float ClosestPoints(float x[ ], float y[ ], int n);
int main()
{
int n;
float x[1000], y[1000];
cin>>n;
for(int i=0;i<n;i++)
{
cin>>x[i];
}
for(int i=0;i<n;i++)
{
cin>>y[i];
}
float min_distance = ClosestPoints(x, y, n);
cout<<min_distance;
return 0;
}
float ClosestPoints(float x[ ], float y[ ], int n)
{
//涓ゆ寰幆鎵炬渶灏忚窛绂?
float d=(x[0]-x[1])*(x[0]-x[1])+(y[0]-y[1])*(y[0]-y[1]);
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if(d>(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])){
d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
}
}
float low,high,mid,e=0.0001;
//distance<1 寮€鏂圭粨鏋滃湪0~1涔嬮棿 鍚﹀垯缁撴灉鍦?~d
if(d<1){
low=d;
high=1;
}
else{
low=1;
high=d;
}
//寮€鏂?
while(high-low>e){
mid=(high+low)/2;
if(mid*mid>d){
high=mid;
}
else{
low=mid;
}
}
mid*=1000;
int ret=(int) mid;
mid=(float)ret/1000;
return mid;
}
4:
分治法排序
选择一种本章分治法中介绍的算法,对整数数组进行排序。
#include <iostream>
#include <fstream>
using namespace std;
int length = 100000;
int arr[100000+1];
//start1
void swap(int *a,int *b){
int *temp=a;
a=b;
b=temp;
}
void QuickSort(int a[],int start,int end){
int newstart=start,newend=end;
int mid=(start+end)/2;
int temp=a[mid];
//鍙湁涓€涓厓绱?or 涓婃鎺掑簭鍦ㄨ竟鐣?
if(mid==end || start>end){
return;
}
if(mid==start){
if(a[start]>a[end]){
swap(a[start],a[end]);
}
return;
}
while(end>start){
while(a[start]<temp){
start++;
}
while(end>=start && a[end]>=temp){
end--;
}
if(end>start){
swap(a[start],a[end]);
if(mid==start){
mid=end;
}
}
else{
swap(a[mid],a[start]);
mid=start;
}
}
QuickSort(a,newstart,mid-1);//宸︿晶鍫?
QuickSort(a,mid+1,newend);//鍙充晶鍫?
}
//end1
int main()
{
ifstream inFile("array.dat", ios::in | ios::binary);
if (!inFile) {
cout << "error" << endl;
return 0;
}
for (int i = 1; i <= length; i++)
{
inFile.read((char *)&arr[i], sizeof(int));
}
inFile.close();
//start2
QuickSort(arr,0,length);
//end2
ofstream outFile("sorted.dat", ios::out | ios::binary);
for (int i = 1; i <= length; i++)
{
outFile.write((char*)&arr[i], sizeof(int));
}
outFile.close();
return 0;
}
5:
减治法求解选择问题
设无序序列T =(r1, r2, …, rn),T 的第k(1≤k≤n)小元素定义为T按升序排列后在第k个位置上的元素。
给定序列T和整数k,寻找T的第k小元素的问题称为选择问题。
采用减治法设计一个高效的算法求解任意选择问题。
代码中数组下标从1开始,第0位置空缺。
#include <iostream>
#include <fstream>
using namespace std;
int length = 100000;
int arr[100000 + 1];
int Partition(int r[],int low,int high){
int i=low,j=high;
while(i<j){
while(i<j&&r[i]<=r[j])
j--;
if(i<j){
int temp=r[i];
r[i]=r[j];
r[j]=temp;
i++;
}
while(i<j&&r[i]<=r[j])
i++;
if(i<j){
int temp=r[i];
r[i]=r[j];
r[j]=temp;
}
}
return i;
}
int SelectMinK(int r[],int low,int high,int k){
int s;
s=Partition(r,low,high);
if(s==k)
return r[s];
if(s>k)
return SelectMinK(r,low,s-1,k);
else
return SelectMinK(r,s+1,high,k);
}
int main()
{
ifstream inFile("input.dat", ios::in | ios::binary);
if (!inFile) {
cout << "error" << endl;
return 0;
}
int k = 0;
inFile.read((char *)&k, sizeof(int));
for (int i = 1; i <= length; i++)
{
inFile.read((char *)&arr[i], sizeof(int));
}
inFile.close();
int v = 0; //Put the result in this variable.
SelectMinK(arr,0,length,k);
v = arr[k];
ofstream outFile("output.dat", ios::out | ios::binary);
outFile.write((char*)&v, sizeof(int));
outFile.close();
return 0;
}
6:
【问题描述】
给定一个序列,如果其中有些元素(也可能没有)被省略,则我们可以得到该序列的一个子序列。给定一个序列X = <x1...xn> ,另一个序列Z满足条件,存在严格递增索引序列I=<i1...ik>,使得对于所有j = 1,2,…,k, 有xij=zj,则称Z= <z1...zk>是X的子序列。
例如,Z = <a, b, f, c>是X = <a, b, c, f, b, c>的子序列。
给定两个序列X和Y,问题是求出X和Y的最大长度公共子序列的长度。
【输入形式】
两个给定字符串
【输出形式】
两个序列最大长度公共子序列的长度。
【样例输入】
abcfbc abfcab
【样例输出】
4
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
char str1[1000],str2[1000];
//定义取最大值函数
int fmax(int a, int b) {
if(a > b) return a;
else return b;
}
//求公共子序列函数
int longestCommonSubsequence(char* text1, char* text2) {
int m = strlen(text1), n = strlen(text2);
int dp[m + 1][n + 1];
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= m; i++) {
char c1 = text1[i - 1];
for (int j = 1; j <= n; j++) {
char c2 = text2[j - 1];
if (c1 == c2) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
dp[i][j] = fmax(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[m][n];
}
//主函数
int main(){
scanf("%s %s",&str1,&str2);
printf("%d",longestCommonSubsequence(str1,str2));
return 0;
}
动态规划求最长递增子序列
输出最长递增子序列的长度
#include <iostream>
#include <fstream>
using namespace std;
int length=100;
int arr[100];
int IncreaseOrder(int a[], int n);
int main(){
for(int i = 0; i < length; i++){
cin >> arr[i];
}
int result = IncreaseOrder(arr, length);
cout << result;
return 0;
}
int inline fmax(int a,int b){
return (a>b ? a : b);
}
#include <malloc.h>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
int IncreaseOrder(int a[],int n){
int *dp=(int*)malloc(sizeof(int)*n),ret=0,max=0;
memset(dp,0,sizeof(dp));
dp[1]=1;
for(int i=2;i<=n;i++){
max=0;
for(int j=1;j<i;j++){
if(a[i-1]>a[j-1]){
max=fmax(max,dp[j]);
}
}
dp[i]=max+1;
ret=fmax(ret,dp[i]);
}
return ret;
}
/*
int IncreaseOrder(int a[],int n){
int dp[n+1];
for(int i=0;i<=n;i++){
dp[i] = 1;
}
int res=1;
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
if(a[i-1]>a[j-1]){
dp[i]=fmax(dp[i],dp[j]+1);
res=fmax(res,dp[i]);
}
}
}
return res;
}
*/