C++经典题目,初学者快速入门!【附有解析】

题目一:1-100各类数之和

(1)求1+2+3+…+100的和

简单的一个for循环的练习,从1遍历到100,每次递增1.

#include<iostream>
using namespace std;

int main(){
	int sum=0;	//定义一个变量存储总和
	for(int i=1;i<=100;i++){	//for循环遍历
		sum+=i;			//每次累加,更新sum值
	}
	cout<<"1+2+3+...+100和为"<<sum;
}

(2)求1+3+5+…+99的奇数和

循环的练习,从1遍历到100,每次递增2,保证都是奇数。

#include<iostream>
using namespace std;

//for循环
void fun_for(){
	int sum=0;
	for(int i=1;i<=100;i+=2){
		sum+=i;
	}
	cout<<"1+3+5+7..+99和为"<<sum<<endl;
} 

//while循环
void fun_while(){
	int sum=0,n=1;
    while(n<=99){
		sum+=n;
		n+=2;
	}
	cout<<"1+3+5+7..+99和为"<<sum<<endl;	
} 

int main(){
	fun_for();
	fun_while();
	
return 0;
}

(3)求1+1/2+1/3+…+1/100的和

可以观察到,分子都是1,分母是从1逐一递增到100.
我们可以把分母这个变量,拿去遍历再求和。

#include<iostream>
using namespace std;

int main(){
	float sum=0;
	for(int i=1;i<=100;i+=1){
		sum+=1.0/i;		//1.0是为了转换数据类型,因为i还是整型
	}
	cout<<"1+1/2+1/3+...+1/100和为"<<sum;
	//printf("%.2f\n",sum);	 保留两位小数
} 

若结尾保留两位小数,则要.2f,如代码中注释的部分。

我们也可写成递归的形式,递归的出口是n==1,返回一个double类型的总和。

#include<iostream>
using namespace std;

double sum(int n){		//递归的求和函数,返回值是double类型,函数名是sum,传入参数是整型的n
	if(n==1){
		return 1.0;		//返回double值
	}
	return 1.0/n+sum(n-1);		//若n不等于1,则一直return这段语句
}

int main(){
	int n=100;
	double result = sum(n);		//调用函数sum,传入参数n,把函数sum返回的值 赋值给变量result
	printf("1+1/2+1/3+...+1/100和为%.2f",result);
	
	return 0;
} 

若需要自定义n,可以使用cin>>n,自己输入n的值,结尾改成printf("1+1/2+1/3+...+1/%d和为%.2f",n,result);n是分母,只能输入正数。

(4)求-1+1/2-1/3+1/4…-1/99+1/100的和

仔细观察可以看出,与上一题不同之处在于符号的正负,奇数位为负,偶数位为正.
我们此时需要写一个if语句来判断奇数偶数。

#include<iostream>
using namespace std;

int main(){
	float sum=0;
	for(int i=1;i<=100;i++){
		if(i%2==0)		//若i是偶数
			sum+=1.0/i;		//则sum加上1.0/i
		else
			sum-=1.0/i;
	}
	cout<<"-1+1/2-1/3+...+1/100和为"<<sum;
	//printf("%.2f\n",sum);	
} 

题目二:斐波那契数列(Fibonacci Sequence)又称黄金分割数列

Q:设一对大兔子每月生一对小兔子,每对新生兔在出生一个月后又下崽,假若兔子都不死亡。问:一对兔子一年能繁殖成多少对兔子?

经典的递归问题
当n=1或者2时,第n项的值为1;
当n>2时候,这个数列的第n项的值就是它前面两项之和。

///第n个fibonacci数可递归如下:
int fibonacci(int n){
	if(n==1||n==2)
		return 1;
	else
		return fibonacci(n-1)+fibonacci(n-2);
}

回到这道题。

#include<iostream>
using namespace std;

int fib(int n){		
	if(n==1||n==2)
		return 1;
	else
		return fib(n-1)+fib(n-2);
}
int main(){
	int n;		//天数
	cout<<"请输入天数:";
	cin>>n;
	cout<<"第"<<n<<"天共有兔子"<<fib(n)<<"对";
	return 0;
}

如果不使用递归呢?
我们可以设置三个变量作为前天、昨天、今天的兔子数量,每过一天就及时更新这些数据。

#include<iostream>
using namespace std;

//f当天兔子对数
//f1昨天兔子对数
//f2前天兔子对数
 
int main(){
	int f1=1,f2=1,f;             //第1.2天都只有一只兔子 
	for(int i=3;i<=10;i++){      //从第三天开始,到第十天
		f=f1+f2;				//每过一天,今天的兔子=昨天+前天
		printf("%d天共有兔子%d对\n",i,f);
		f2=f1;					//更新前天的数据
		f1=f;					//更新昨天的数据
	}
	return 0; 
} 

在这里插入图片描述

题目三:判断素数

素数一般指质数。质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

暴力法

根据素数的定义,不能被2~n-1之内的数整除的整数n就被称为素数。所以我们从2跑到n-1,每次取模判断即可,这是最直观的一种方法。

bool isPrime_1(int num)
{
    for(int i=2;i<=num-1;i++)
      if(num%i==0)	//若被整除,则说明不是素数,返回0
         return 0;
    return 1;
}

开根号法

对于每个数n,其实并不需要从2判断到n-1,我们知道,一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n),据此,上述代码中并不需要遍历到n-1,==遍历到sqrt(n)==即可,因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数!所以从2跑到sqrt(n)就可以了。

bool isPrime_2(int num)
{
	double tmp=num-1;
    for(int i=2;i<=sqrt(tmp);i++)
      if(num%i==0)
         return 0;
    return 1;
}

在 头文件中声明的 sqrt() 函数的参数和返回值都是浮点数类型

Q:遍历101-200的素数。

#include <iostream>
#include <cmath>
using namespace std;

bool isPrime(int num) {
    if (num <= 1) {
        return false;
    }
    for (int i = 2; i <= sqrt(num); i++) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}

int main() {
    int count = 0;
    cout << "素数列表:\n";
    for (int i = 101; i <= 200; i++) {
        if (isPrime(i)) {
            cout << i << " ";
            count++;
        }
    }
    cout << "\n101到200之间的素数个数为:" << count << endl;
    return 0;
}

在这里插入图片描述

题目四:打印九九乘法表

我们可以知道,乘法表的格式是列数 * 行数 = 结果值。那么这里面就有三个变量,分别是列数、行数、结果值。
我们假设行数是i,列数是j,那么结果值可以为i*j(这里就直接写表达式,不再定义变量)

对于行数i,遍历从1到9,那列数j呢,也是直接遍历从1到9吗?
nonono,你可以试试,打印出来会是一个9*9的长方形乘法表,不是三角形的。我们可以发现,九九乘法表的每一行的列数是<=行数的,那么由此我们也找到了列数的限制范围。

#include<iostream>
using namespace std;

//简单版
int main(){
	for(int i=1;i<=9;i++){
		for(int j=1;j<=i;j++)
			printf("%d*%d=%-5d",j,i,i*j);
			cout<<endl;
	}
	return 0;
}

在这里插入图片描述

#include<iostream>
using namespace std;

const int WIDTH=5;	//宏定义,所有的WIDTH的值均为5
int main(){
	//打印列头
	cout<<setw(WIDTH)<<'*' ;	//setw()字段宽度限制
	for(int i=1;i<=9;i++)
		cout<<setw(WIDTH)<<i;
	cout<<endl;
	for(int i=1;i<10*WIDTH;i++){
			cout<<'-';
		}
	cout<<endl;

	for(int i=1;i<=9;i++){
		cout<<setw(WIDTH)<<i;	//最左边的表格列
		for(int j=1;j<=i;j++)
			cout<<setw(WIDTH)<<i*j;
		for(int j=i;j<=9;j++)
			cout<<setw(WIDTH)<<' ';
		cout<<endl;
		}
	return 0;
}

setw(int n)是c++中在输出操作中使用的字段宽度设置,设置输出的域宽,n表示字段宽度。

在这里插入图片描述

题目五:猴子爬杆

(1)猴子每天爬3米,再向下退1米,到第十天后刚好到达杆顶,问杆子高度。

爬十天,前九天每天爬2米,最后一天爬3米

#include<iostream>
using namespace std;

int main(){
	int day=1,high=0;
	
	while(day<10){
		high=high+2;
		day++;
	}
	high=high+3;
	cout<<high;
	
	return 0;
} 

(2)杆子20米,猴子每天爬3米,下退1米,问猴子第几天爬到顶

最后一天爬的总高度>20米,其实就是求当达到这个条件的时候的天数。

#include<iostream>
using namespace std;

int main(){
	int day=1,high=0;
	
	while((high+3)<20){
		high=high+2;
		day++;
	}
	cout<<day;
	
	return 0;
} 

题目六:猴子吃桃

Q:猴子每天吃掉一半的桃,再贪吃一个,到第10天就剩1个桃子,问最初有多少桃子?

已知最后一天的天数和桃子个数,往前推就可推出总数。

#include<iostream>
using namespace std;

int main(){
	int day=9,x=1;

	while(day>0){
		x=(x+1)*2;
		day--;
	}
	cout<<x;
	return 0;
} 

题目七:水仙花数

Q:遍历从100到1000的水仙花数

水仙花数:个位3+十位3+百位3=数值

第一步:分解一个三位数的个位,十位,百位;
第二步:判断是否满足水仙花数的条件;
第三步:通过循环遍历所有的三位数;

#include<iostream>
using namespace std;

int main(){
	int ge,shi,bai;
	for(int n=100;n<=1000;n++){
		ge=n%10;
		shi=n%100/10;
		bai=n/100;
		
		if(ge*ge*ge+shi*shi*shi+bai*bai*bai==n)
			cout<<n<<"是水仙花数"<<endl; 
	}
	return 0; 
}

题目八:菱形打印

Q:输入一个正整数m,打印出高度有2*m-1的菱形

可在草稿纸上罗列出m=1,2,3,4时候的菱形,寻找m与空格和*的关系,寻找行数与空格和*的关系,先用数学公式表示,再翻译为代码。

#include<iostream>
using namespace std;

int main(){
	int m;
	cin>>m;
	
	for(int i=1;i<=m;i++){  //行数
		for(int j=1;j<=m-i;j++)		//空格
			cout<<" ";
		for(int k=1;k<=2*i-1;k++)	//*
			cout<<"*";
		cout<<endl;
	}
	
	for(int i=2;i<=m;i++){	//这里的行数没有计算长的那一行,所以是m-1行
		for(int j=1;j<i;j++)
			cout<<" ";
		for(int k=1;k<=2*m+1-2*i;k++)
			cout<<"*";
		cout<<endl;
	}
}

在这里插入图片描述

题目九:判断位数并倒叙输出

Q:输入一个整数,倒序输出每个位数的数值。如输入456,输出6 5 4 .

#include<iostream>
#include<cmath>		//注意导入库函数
using namespace std;

int main(){
	int m,i=1;
	printf("请输入一个整数:");
	scanf("%d",&m);
	
	printf("%3d",abs(m)%10);	//输出个位数的数值
	while((m=abs(m)/10)>0){  	//abs求绝对值 
		printf("%3d",m%10);
		i++;     				 //i统计循环次数,位数为循环次数+1 
	}
	printf("输入的是%d位数\n",i);
	
	return 0;
}

判断位数,并倒叙输出
m=123 m%10=3
m=m/10=12 m%10=2
m=m/10=1 m%10=1

abs (n)函数定义在 或 <math.h> 头文件中,返回参数n的绝对值

题目十:最大公约数与最小公倍数

Q:先输入大数字a,再输入小数字b,求这两个数字的最大公约数和最小公倍数。

最大公约数算法如下:

穷举法

从较小的数开始,遍历到1,一次一次查询是否能被两个数字所整除。由于是从大开始遍历到小,所以首先得到的结果就是最大公约数。

void fun1(){
	int a,b;
	cin>>a>>b;
	for(int i=b;i>0;i--){
		if(a%i==0&&b%i==0){
	      cout<<a<<"和"<<b<<"的最大公约数是"<<i<<endl;
		  break; 
		}
	}
}

欧几里德算法(辗转相除法)

gcd(a,b)=gcd(b,a%b)
a%b为0时,两数最大公约数为b

long gcd(int a,int b){
	if(a%b==0)
		return b;	//b为最大公约数
	return gcd(b,a%b);
}

最大公约数x最小公倍数=axb

  cout<<"最大公约数是"<<m<<endl;
  cout<<"最小公倍数是"<<(a*b)/n<<endl; 

题目十一:字符串倒序

#include<iostream>
#include<string>
#include<cmath>
using namespace std;

int main(void){
	char str[]="student";
	char ch;
	int len=strlen(str);	//strlen(),获取字符串长度
	for(int i=0;i<len/2;i++){	//对半分开,首尾交换字符,下面三行代码类似冒泡排序里的交换数值
		ch=str[i];
		str[i]=str[len-i-1];
		str[len-i-1]=ch;		
	}
	puts(str);	//puts(),用于输出一个字符串并换行
	return 0;
}

题目十二:杨辉三角

第一步:定义一个二维数组,赋初值为1
第二步:从第2行 第2列开始,当前数=上一行的数=上一行前面的数
第三步:只输出左下角部分数据
第四步:每行加上数量不等的数,使其居中

#include<iostream>
using namespace std;

int main(){
	int data[9][9]; 
	for(int i=0;i<9;i++){
		for(int j=0;j<9;j++){
			data[i][j]=1;
		}
	}
	
	for(int i=1;i<9;i++){
		for(int j=1;j<9;j++){
			data[i][j]=data[i-1][j]+data[i-1][j-1];	//当前数=上一行的数=上一行前面的数
		}
	}
	
	for(int i=0;i<9;i++){
		for(int k=0;k<26-6*i/2;k++)   //i/2:居中只需左边加空格; *6:输出时%6d; 用26剪:不大不小刚刚好 
			printf(" ");			  
		for(int j=0;j<i;j++)          //输出左下角的数据
			printf("%6d",data[i][j]);
		printf("\n");
	}
	return 0;
}

在这里插入图片描述

题目十三:完数

Q:输入一个正整数,判断是否为完数

如果一个数等于它的因子之和 ,则这个数为完数
例如:6的因子是1,2,3,且123=6,故6为完数

#include<iostream>
using namespace std; 

int main(){
	int m,s=0;	//s为m的因子的总和值
	printf("请输入一个正整数:");
	scanf("%d",&m);
	for(int i=1;i<m;i++){
		if(m%i==0)	//如果i是因子,则加到s值中
			s+=i;
	}
	if(m==s)
		printf("%d是一个完数\n",m);
	else
		printf("%d不是一个完数\n",m);
}

题目十四:求阶乘

Q:求出1-10的阶乘,最后累加求和

#include<iostream>
using namespace std;

int main(){
	unsigned s=0;	//使用unsigned类型可以确保结果不会出现负数;s是阶乘和
	for(int n=1;n<=10;n++){
		unsigned jie=1;		//每个数字的阶乘值
		int i=1; 
		for(;i<=n;i++)
			jie*=i;	
		printf("%d!=%u\n",i-1,jie);		//上一行的for循环结束后,i被++了,比n大了一
		s+=jie;
	}
	printf("1!+2!+...+10!=%u\n",s);	//注意是%u噢,对应的unsighed

	return 0;
} 

在这里插入图片描述

递归:

#include<iostream>
using namespace std;

int fac(int n){
	int f=0;
	if(n<0)
		cout<<"n<0,error!";
	else if(n==0||n==1)
		f=1;
	else f=n*fac(n-1);
	return f;
	
} 
int main(){
	int n,y;	//n为被阶乘的数字,y为n的阶乘值
	cin>>n;
	y=fac(n);
	cout<<n<<"!="<<y;
	return 0;
} 

题目十五:求字符串符号长度函数

Q:手写strlen()函数,求字符串符号长度函数

以查询到字符为'\0'的情况为终止条件,此时字符串的字母已经遍历完

#include<iostream>
using namespace std;

int strlen(const char *p){	//函数类型int,函数名strlen,输入的参数是char型的常量指针p
	int count=0;
	while(*p!='\0'){	//字符串最后的字符是'\0'
		count++;
		p++;
	}
	return count;
}
int main(){
	char str[]="hello";
	printf("%d\n",strlen(str));
	return 0;
}

常量指针:指针本身是可变的,但指针所指向的值是不可变的。声明方式为 const int *ptr;,意味着不能通过该指针修改所指向的值,但可以改变指针指向的位置。
指针常量:指针本身是不可变的,但指针所指向的值是可变的。声明方式为int *const ptr;,意味着指针本身不能指向其他位置,但可以通过该指针修改所指向的值。

题目十六:冒泡排序

经典题目,必会

#include<iostream>
using namespace std;

void bubble(int[],int);		//函数声明,int[] 表示一个整型数组,等效于int*

int main(){
	int array[]={55,2,6,4,32,12,9,73,26,37};
	int len=sizeof(array)/sizeof(int);	//数组长度=数组的总字节数/数据类型的字节数
	for(int i=0;i<len;i++)
		cout<<array[i]<<",";	//输出原先的数组
	cout<<"\n\n";
	
	bubble(array,len);
}

void bubble(int a[],int size){	//传入两个参数,数组和数组长度
	for(int pass=1;pass<size;pass++){	//外层循环控制遍历数组的次数,每次遍历都会将当前最大(或最小)的元素移动到正确位置,只需size-1次
		for(int i=0;i<size-pass;i++)	//内层循环用于实际比较相邻元素并进行交换操作
			if(a[i]>a[i+1]){
				int temp=a[i];
				a[i]=a[i+1];
				a[i+1]=temp;
			}
			for(int i=0;i<size;i++)		//打印每一次排序后的数组
				cout<<a[i]<<",";
			cout<<endl;
	}
}

sizeof(x), 计算出x在内存中所占字节数.

题目十七:数列求和

Q:a[n]=1/(n+1)+2/(n+1)+……+n/(n+1),求前n项和S[n]

#include<iostream>
using namespace std;

int main(){
	cout<<"请输入一个正整数";
	int n;
	scanf("%d",&n);
	if(n<=0){
		cout<<"输入的值不合法";
		return 0;
	}
	float a=0,s=0;
	for(int j=1;j<=n;j++){
		for(int i=1;i<=j;i++){
			a+=i/(j+1.0);
		}
		printf("a[%d]=%-8.4f",j,a);
		s+=a;
	}
	printf("\ns[%d]=%.4f\n",n,s);
	
	return 0;
} 

%-8.4f:用来输出浮点数,具体含义如下:
-:表示左对齐。
8:表示输出的总宽度为 8 个字符,包括小数点和小数部分。
.4:表示保留 4 位小数。
f:表示输出的是浮点数。
在这里插入图片描述

题目十八:输入日期第几天

Q:输入日期是第几天,判断一个日期是当年的第几天,判断月份的天数、判断闰年、判断每个月的天数

#include<iostream>
using namespace std;

int main(){
	int sum=0;
	int day,month,year;
	printf("请输入日期(以空格区分)(例如:2024 1 1)\n");
	scanf("%d%d%d",&year,&month,&day);
	
	if(day>31){
		cout<<"输入错误";
		return 0;
	}
	switch(month-1) {
		case 11:sum+=30;
		case 10:sum+=31;
		case 9:sum+=30;
		case 8:sum+=31;
		case 7:sum+=31;
		case 6:sum+=30;
		case 5:sum+=31;
		case 4:sum+=30;
		case 3:sum+=31;
		case 2:
			if((year%100!=0&&year%4==0)||year%400==0){
				sum+=28;
			}
			else
				sum+=29;
		case 1:sum+=30;break;
		case 0:break;
		default:
			cout<<"输入错误";
			return 0;
	}
	printf("当前日期是今年的第%d天",sum+day);
	
	return 0; 
}

此代码还可完善,缺少部分的错误输入警告

题目十九:输出1234组成不重复的三位数

Q:有1,2,3,4个数字能组成多少个没有重复数字的三位数?输出这些三位数

#include<iostream>
using namespace std;

int main(){
	for(int i=1;i<=4;i++){	//百位
		for(int j=1;j<=4;j++){	//十位
			for(int k=1;k<=4;k++){	//个位
				if(i!=j&&j!=k&&i!=k)	//没有重复
				printf("%6d",i*100+j*10+k);
			}
		} 
	}
	printf("\n");
	return 0;
}

题目二十:数组对角线之和

Q:求下列数组的对角线之和

j=0j=1j=2
i=0123
i=1456
i=2789

L1=1+5+9=arr[0][0]arr[1][1]+arr[2][2] i==j
L2=3+5+7=arr[0][2]arr[1][1]+arr[2][0] i+j=2
对角线之和=L1+L2-arr[1][1]

#include<iostream>
using namespace std;

#define LEN 3 //定义一个符号常量,代理程序中的字面常量
int main(){
	int L1,L2,s;
	L1=L2=s=0;
	int arr[][LEN]={{1,2,3},{4,5,6},{7,8,9}};
	for(int i=0;i<LEN;i++){
		L1+=arr[i][i];		//主对角线
		L2+=arr[i][LEN-1-i];		//次对角线
	}
	s=L1+L2-arr[(LEN-1)/2][(LEN-1)/2];
	printf("对角线之和为:%d\n",s); 
	return 0;
}

题目二十一:数组中的最值与均值

#include<iostream>
using namespace std;

int main(){
	int data[]={21,32,56,79,98,64,31,51,84,67};
	int max,min,sum=0;
	float avg;
	max=min=data[0];
	
	for(int i=1;i<10;i++){
		if(max<data[i])
			max=data[i];
		if(min>data[i])
			min=data[i];
		sum+=data[i];
	} 
	avg=sum/10.0;
	cout<<"最大值是"<<max<<endl
		<<"最小值是"<<min<<endl
		<<"平均值是"<<avg<<endl;
	return 0;
}

参考资料

1.b站up主 慕码人CPL
2. 大一自己的学习资料

  • 37
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值