分享——有趣的题目
从今天开始我打算开启一个新的系列,这个系列主要记录我最近想起的经典的题目,刷到的有趣的题目,和一些有深度的题目,算是一个题目的收集系列。开一个新坑希望大家喜欢。
题目零:1/n的累加
难度:★★
#include <iostream>
using namespace std;double gets(int n)
{
double r=0.0;
for(int i=1;i<n+1;i++)
{
r+=1.0/i;
}
return r;
}int main()
{
int n;
cin>>n;
cout<<gets(n)<<endl;
return 0;
}
题目一:求两个数的最大公约数。
难度:★★
#include<iostream>
using namespace std;int ojld(int m,int n)
{
int r=m%n;
while(r!=0)
{
m=n;
n=r;
r=m%n;
}
return n;
}int main()
{
int m,n;
cout << "输入两个数" << endl;
cin>>m>>n;
cout << "zuidagongyueshu"<<ojld(35,25) << endl;
return 0;
}
题目二:数组左移的循环
难度:★★★★
#include <iostream>
using namespace std;// 函数用于向左循环移位数组
void leftRotate(int arr[], int n, int d) {// 如果d是n的倍数,那么数组将保持不变if (d == 0) return;d = d % n; // 如果d大于n,则取模int temp[n]; // 用于临时存储数组// 先将第一部分的元素复制到temp中for (int i = 0; i < d; i++) {temp[i] = arr[n - d + i];}
两种方式://1 然后将第二部分的元素复制到temp中,注意这里j从d开始for (int i = 0, j = d; i < n - d; i++, j++) {temp[j] = arr[i];}/* //2 复制剩余的元素到tempfor (int i = d, j = 0; i < n; i++, j++) {temp[j] = arr[i - d];}*/// 将temp中的元素复制回原数组for (int i = 0; i < n; i++) {arr[i] = temp[i];}
}/*
在代码中,if (d == 0) return; 和 d = d % n; 这两行代码各自扮演着重要的角色,尤其是在处理数组旋转或任何需要周期性或循环性操作的场景中。if (d == 0) return;这行代码检查变量 d(通常表示要旋转的步数或次数)是否等于 0。如果是,函数立即返回,不执行任何旋转操作。这是因为旋转 0 次意味着数组应该保持不变,所以没有必要进行任何计算或修改。这可以提高代码的效率,避免不必要的计算。d = d % n;这行代码对 d 进行模 n 操作,其中 n 是数组的长度。模运算 % 的结果是 d 除以 n 的余数。这个操作有几个目的:确保 d 的值在有效范围内:如果 d 大于或等于 n,那么实际上只需要旋转 d % n 次就能达到相同的效果。例如,如果数组有 5 个元素(n = 5),并且你想旋转 7 次(d = 7),那么实际上只需要旋转 2 次(7 % 5 = 2),因为旋转 5 次或更多次将会使数组回到原始状态。
避免无效操作:通过确保 d 的值小于 n,可以避免执行无效或多余的旋转操作。综上所述,这两行代码在数组旋转函数中非常重要,它们确保了函数的效率和正确性。首先,它们检查是否需要执行旋转操作(d 是否为 0)。然后,它们确保旋转的次数在有效范围内(d 是否小于 n),从而避免了不必要的计算或无效操作。
*/// 打印数组的函数
void printArray(int arr[], int size) {for (int i = 0; i < size; i++)cout << arr[i] << " ";cout << endl;
}// 主函数
int main() {int arr[] = {1, 2, 3, 4, 5, 6, 7};int n = sizeof(arr) / sizeof(arr[0]);int d = 3; // 向左移动3个位置cout << "原始数组: ";printArray(arr, n);leftRotate(arr, n, d);cout << "向左旋转 " << d << " 次后的数组: ";printArray(arr, n);return 0;
}
题目三:冒泡排序和快速排序的计算速度比较
难度:★★★★★★
#include <iostream>
#include <ctime>
#include <cmath>
#include <cassert>
using namespace std;void BubbleSort( int *r , int n ) ;
void QuickSort(int *data , int first, int last);
int Partition( int *data, int first, int last );
int *generateRadomArray(int n , int rangeL , int rangeR);int main()
{int i = 4; int n = pow(10,i); //待排序的数据规模clock_t startTime, endTime;int *arr = generateRadomArray(n,0,n);startTime = clock();BubbleSort( arr , n );endTime = clock();cout << "data size: " << n << endl;cout << "Time cost: " << double(endTime-startTime)/CLOCKS_PER_SEC << "s" << endl; startTime = clock();QuickSort( arr, 0, n-1 );endTime = clock();cout << "data size: " << n << endl;cout << "Time cost: " << double(endTime-startTime)/CLOCKS_PER_SEC << "s" << endl; delete[] arr; return 0;
}void BubbleSort( int *r , int n )
{ int temp, bound, exchange = n-1;while( exchange != 0){bound = exchange;exchange = 0;for( int j = 0; j < bound; j++ ) //排序区间[1,bound] if(r[j] > r[j+1]){temp = r[j]; r[j] = r[j+1]; r[j+1] = temp;exchange = j; }}
}int Partition( int *data, int first, int last )
{int i = first, j = last, temp; //初始化一次划分的区间while (i < j) {while (i < j && data[i] <= data[j]) j--; //右侧扫描if (i < j) { temp = data[i]; data[i] = data[j]; data[j] = temp; i++; }while (i < j && data[i] <= data[j]) i++; //左侧扫描if (i < j) {temp = data[i]; data[i] = data[j]; data[j] = temp; j--; }}return i; // i为轴值记录的最终位置
}void QuickSort(int *data , int first, int last)
{ if (first >= last) return; //区间长度为1,递归结束else {int pivot = Partition(data, first, last); //一次划分QuickSort(data, first, pivot-1); //对左侧子序列进行快速排序QuickSort(data, pivot+1, last); //对右侧子序列进行快速排序 }
}int *generateRadomArray(int n , int rangeL , int rangeR)
{assert( n > 0 && rangeL <= rangeR ); //断言处理 int *arr = new int[n]; //数据规模为nsrand(time(NULL));for(int i = 0 ; i < n ; i++ ){arr[i] = rand() % (rangeR - rangeL + 1) + rangeL;} return arr;
}
以上的四个题目就是我最近遇到的有趣的题目和我刚开始不会的题目,都分享在这,尤其是前两个题目算是经典的问题了。本周之内我会发一篇解析,进行一个简单的分析和解释。
感谢大家阅读,如果大家喜欢这个系列麻烦大家多多点赞加关注,感谢大家。